diff --git a/.fossil-settings/empty-dirs b/.fossil-settings/empty-dirs new file mode 100644 index 0000000000..64fb6839df --- /dev/null +++ b/.fossil-settings/empty-dirs @@ -0,0 +1 @@ +compat diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob new file mode 100644 index 0000000000..5282ca9c3d --- /dev/null +++ b/.fossil-settings/ignore-glob @@ -0,0 +1 @@ +compat/* diff --git a/Makefile.in b/Makefile.in index bce57b717b..96e2eb11f8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -89,6 +89,9 @@ TCC += $(OPT_FEATURE_FLAGS) # ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". TCC += $(OPTS) +# Add in compile-time options for some libraries used by extensions +TCC += @HAVE_ZLIB@ + # Version numbers and release number for the SQLite being compiled. # VERSION = @VERSION@ @@ -166,7 +169,8 @@ USE_AMALGAMATION = @USE_AMALGAMATION@ # LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ - callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \ + callback.lo complete.lo ctime.lo \ + date.lo dbpage.lo dbstat.lo delete.lo \ expr.lo fault.lo fkey.lo \ fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \ fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \ @@ -176,17 +180,17 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ func.lo global.lo hash.lo \ icu.lo insert.lo json1.lo legacy.lo loadext.lo \ main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \ - memjournal.lo \ + memdb.lo memjournal.lo \ mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \ pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ random.lo resolve.lo rowset.lo rtree.lo \ sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \ table.lo threads.lo tokenize.lo treeview.lo trigger.lo \ - update.lo util.lo vacuum.lo \ + update.lo upsert.lo util.lo vacuum.lo \ vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \ - utf.lo vtab.lo + window.lo utf.lo vtab.lo # Object files for the amalgamation. # @@ -215,6 +219,7 @@ SRC = \ $(TOP)/src/complete.c \ $(TOP)/src/ctime.c \ $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ $(TOP)/src/dbstat.c \ $(TOP)/src/delete.c \ $(TOP)/src/expr.c \ @@ -235,6 +240,7 @@ SRC = \ $(TOP)/src/mem2.c \ $(TOP)/src/mem3.c \ $(TOP)/src/mem5.c \ + $(TOP)/src/memdb.c \ $(TOP)/src/memjournal.c \ $(TOP)/src/msvc.h \ $(TOP)/src/mutex.c \ @@ -265,7 +271,7 @@ SRC = \ $(TOP)/src/rowset.c \ $(TOP)/src/select.c \ $(TOP)/src/status.c \ - $(TOP)/src/shell.c \ + $(TOP)/src/shell.c.in \ $(TOP)/src/sqlite.h.in \ $(TOP)/src/sqlite3ext.h \ $(TOP)/src/sqliteInt.h \ @@ -278,6 +284,7 @@ SRC = \ $(TOP)/src/trigger.c \ $(TOP)/src/utf.c \ $(TOP)/src/update.c \ + $(TOP)/src/upsert.c \ $(TOP)/src/util.c \ $(TOP)/src/vacuum.c \ $(TOP)/src/vdbe.c \ @@ -297,7 +304,8 @@ SRC = \ $(TOP)/src/where.c \ $(TOP)/src/wherecode.c \ $(TOP)/src/whereexpr.c \ - $(TOP)/src/whereInt.h + $(TOP)/src/whereInt.h \ + $(TOP)/src/window.c # Source code for extensions # @@ -342,7 +350,8 @@ SRC += \ $(TOP)/ext/icu/icu.c SRC += \ $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/rtree.c + $(TOP)/ext/rtree/rtree.c \ + $(TOP)/ext/rtree/geopoly.c SRC += \ $(TOP)/ext/session/sqlite3session.c \ $(TOP)/ext/session/sqlite3session.h @@ -362,6 +371,7 @@ SRC += \ parse.c \ parse.h \ config.h \ + shell.c \ sqlite3.h # Source code to the test files. @@ -393,6 +403,7 @@ TESTSRC = \ $(TOP)/src/test_intarray.c \ $(TOP)/src/test_journal.c \ $(TOP)/src/test_malloc.c \ + $(TOP)/src/test_md5.c \ $(TOP)/src/test_multiplex.c \ $(TOP)/src/test_mutex.c \ $(TOP)/src/test_onefile.c \ @@ -404,10 +415,12 @@ TESTSRC = \ $(TOP)/src/test_server.c \ $(TOP)/src/test_superlock.c \ $(TOP)/src/test_syscall.c \ + $(TOP)/src/test_tclsh.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_window.c \ $(TOP)/src/test_wsd.c \ $(TOP)/ext/fts3/fts3_term.c \ $(TOP)/ext/fts3/fts3_test.c \ @@ -417,18 +430,23 @@ TESTSRC = \ # Statically linked extensions # TESTSRC += \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/test_expert.c \ $(TOP)/ext/misc/amatch.c \ $(TOP)/ext/misc/carray.c \ $(TOP)/ext/misc/closure.c \ $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ + $(TOP)/ext/misc/explain.c \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/fuzzer.c \ $(TOP)/ext/fts5/fts5_tcl.c \ $(TOP)/ext/fts5/fts5_test_mi.c \ $(TOP)/ext/fts5/fts5_test_tok.c \ $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/mmapwarm.c \ $(TOP)/ext/misc/nextchar.c \ + $(TOP)/ext/misc/normalize.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ $(TOP)/ext/misc/remember.c \ @@ -436,7 +454,8 @@ TESTSRC += \ $(TOP)/ext/misc/spellfix.c \ $(TOP)/ext/misc/totype.c \ $(TOP)/ext/misc/unionvtab.c \ - $(TOP)/ext/misc/wholenumber.c + $(TOP)/ext/misc/wholenumber.c \ + $(TOP)/ext/misc/zipfile.c # Source code to the library files needed by the test fixture # @@ -448,6 +467,7 @@ TESTSRC2 = \ $(TOP)/src/build.c \ $(TOP)/src/ctime.c \ $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ $(TOP)/src/dbstat.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ @@ -477,6 +497,7 @@ TESTSRC2 = \ $(TOP)/src/where.c \ $(TOP)/src/wherecode.c \ $(TOP)/src/whereexpr.c \ + $(TOP)/src/window.c \ parse.c \ $(TOP)/ext/fts3/fts3.c \ $(TOP)/ext/fts3/fts3_aux.c \ @@ -533,7 +554,8 @@ EXTHDR += \ $(TOP)/ext/fts3/fts3_hash.h \ $(TOP)/ext/fts3/fts3_tokenizer.h EXTHDR += \ - $(TOP)/ext/rtree/rtree.h + $(TOP)/ext/rtree/rtree.h \ + $(TOP)/ext/rtree/geopoly.c EXTHDR += \ $(TOP)/ext/icu/sqliteicu.h EXTHDR += \ @@ -546,7 +568,8 @@ TESTPROGS = \ sqlite3$(TEXE) \ sqlite3_analyzer$(TEXE) \ sqldiff$(TEXE) \ - dbhash$(TEXE) + dbhash$(TEXE) \ + sqltclsh$(TEXE) # Databases containing fuzzer test cases # @@ -555,7 +578,8 @@ FUZZDATA = \ $(TOP)/test/fuzzdata2.db \ $(TOP)/test/fuzzdata3.db \ $(TOP)/test/fuzzdata4.db \ - $(TOP)/test/fuzzdata5.db + $(TOP)/test/fuzzdata5.db \ + $(TOP)/test/fuzzdata6.db # Standard options to testfixture # @@ -564,13 +588,19 @@ TESTOPTS = --verbose=file --output=test-out.txt # Extra compiler options for various shell tools # SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -# SHELL_OPT += -DSQLITE_ENABLE_FTS5 +#SHELL_OPT += -DSQLITE_ENABLE_FTS5 +SHELL_OPT += -DSQLITE_ENABLE_RTREE SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB +SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB +SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB +SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC +SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 +FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000 FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c DBFUZZ_OPT = @@ -596,9 +626,9 @@ libtclsqlite3.la: tclsqlite.lo libsqlite3.la -version-info "8:6:8" \ -avoid-version -sqlite3$(TEXE): $(TOP)/src/shell.c sqlite3.c +sqlite3$(TEXE): shell.c sqlite3.c $(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ - $(TOP)/src/shell.c sqlite3.c \ + shell.c sqlite3.c \ $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h @@ -628,6 +658,9 @@ ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3. $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) +sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h + $(CC) $(CFLAGS) -I. -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS) + dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) @@ -667,7 +700,7 @@ mptest: mptester$(TEXE) sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl - cp tsrc/shell.c tsrc/sqlite3ext.h . + cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . sqlite3ext.h: .target_source @@ -693,6 +726,11 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o $@ $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . +# Rules to build the program that generates the source-id +# +mksourceid$(BEXE): $(TOP)/tool/mksourceid.c + $(BCC) -o $@ $(TOP)/tool/mksourceid.c + # Rules to build individual *.o files from generated *.c files. This # applies to: # @@ -746,6 +784,9 @@ ctime.lo: $(TOP)/src/ctime.c $(HDR) date.lo: $(TOP)/src/date.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c +dbpage.lo: $(TOP)/src/dbpage.c $(HDR) + $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c + dbstat.lo: $(TOP)/src/dbstat.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c @@ -800,6 +841,9 @@ mem3.lo: $(TOP)/src/mem3.c $(HDR) mem5.lo: $(TOP)/src/mem5.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c +memdb.lo: $(TOP)/src/memdb.c $(HDR) + $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c + memjournal.lo: $(TOP)/src/memjournal.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c @@ -878,6 +922,9 @@ trigger.lo: $(TOP)/src/trigger.c $(HDR) update.lo: $(TOP)/src/update.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c +upsert.lo: $(TOP)/src/upsert.c $(HDR) + $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c + utf.lo: $(TOP)/src/utf.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c @@ -926,11 +973,14 @@ wherecode.lo: $(TOP)/src/wherecode.c $(HDR) whereexpr.lo: $(TOP)/src/whereexpr.c $(HDR) $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c +window.lo: $(TOP)/src/window.c $(HDR) + $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c + tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) $(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c + $(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR) $(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c @@ -958,13 +1008,30 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl mv parse.h parse.h.temp $(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c ./mkkeywordhash$(BEXE) >keywordhash.h +# Source files that go into making shell.c +SHELL_SRC = \ + $(TOP)/src/shell.c.in \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/shathree.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/completion.c \ + $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/sqlite3expert.h \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/src/test_windirent.c + +shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl + $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c + + # Rules to build the extension objects. @@ -1085,12 +1152,14 @@ sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) # necessary because the test fixture requires non-API symbols which are # hidden when the library is built via the amalgamation). # -TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 +TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 +TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE TESTFIXTURE_FLAGS += -DBUILD_sqlite TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la TESTFIXTURE_SRC1 = sqlite3.c @@ -1114,14 +1183,17 @@ fulltestonly: $(TESTPROGS) fuzztest ./testfixture$(TEXE) $(TOP)/test/full.test # Fuzz testing -fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) +fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db ./fuzzcheck$(TEXE) $(FUZZDATA) + ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db -fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) +fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db ./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA) + ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db -valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) +valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) + valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db # The veryquick.test TCL tests. # @@ -1151,18 +1223,37 @@ valgrindtest: $(TESTPROGS) valgrindfuzz smoketest: $(TESTPROGS) fuzzcheck$(TEXE) ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) -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){" >> $@ - echo "static const char *zMainloop = " >> $@ - $(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@ - echo "; return zMainloop; }" >> $@ +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in + $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(TEXE): sqlite3_analyzer.c $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) +sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in + $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c + +sqltclsh$(TEXE): sqltclsh.c + $(LTLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) + +sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c + $(LTLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS) + +CHECKER_DEPS =\ + $(TOP)/tool/mkccode.tcl \ + sqlite3.c \ + $(TOP)/src/tclsqlite.c \ + $(TOP)/ext/repair/sqlite3_checker.tcl \ + $(TOP)/ext/repair/checkindex.c \ + $(TOP)/ext/repair/checkfreelist.c \ + $(TOP)/ext/misc/btreeinfo.c \ + $(TOP)/ext/repair/sqlite3_checker.c.in + +sqlite3_checker.c: $(CHECKER_DEPS) + $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ + +sqlite3_checker$(TEXE): sqlite3_checker.c + $(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) + dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo $(LTLINK) -DDBDUMP_STANDALONE -o $@ \ $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) @@ -1179,12 +1270,18 @@ showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS) +showshm$(TEXE): $(TOP)/tool/showshm.c + $(LTLINK) -o $@ $(TOP)/tool/showshm.c + changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) +atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo + $(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) + LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h $(LTLINK) -I. -o $@ $(TOP)/tool/logest.c diff --git a/Makefile.msc b/Makefile.msc index da94288c85..b9fab7c408 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -92,6 +92,29 @@ SPLIT_AMALGAMATION = 0 !ENDIF # <> +# Set this non-0 to have this makefile assume the Tcl shell executable +# (tclsh*.exe) is available in the PATH. By default, this is disabled +# for compatibility with older build environments. This setting only +# applies if TCLSH_CMD is not set manually. +# +!IFNDEF USE_TCLSH_IN_PATH +USE_TCLSH_IN_PATH = 0 +!ENDIF + +# Set this non-0 to use zlib, possibly compiling it from source code. +# +!IFNDEF USE_ZLIB +USE_ZLIB = 0 +!ENDIF + +# Set this non-0 to build zlib from source code. This is enabled by +# default and in that case it will be assumed that the ZLIBDIR macro +# points to the top-level source code directory for zlib. +# +!IFNDEF BUILD_ZLIB +BUILD_ZLIB = 1 +!ENDIF + # Set this non-0 to use the International Components for Unicode (ICU). # !IFNDEF USE_ICU @@ -316,6 +339,12 @@ SQLITE_TCL_DEP = !IF $(MINIMAL_AMALGAMATION)==0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1 !ENDIF OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 !ENDIF @@ -597,6 +626,10 @@ SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) !IFNDEF SHELL_CORE_SRC !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 SHELL_CORE_SRC = +# <> +!ELSEIF $(USE_AMALGAMATION)==0 +SHELL_CORE_SRC = +# <> !ELSE SHELL_CORE_SRC = $(SQLITE3C) !ENDIF @@ -607,16 +640,33 @@ SHELL_CORE_SRC = $(SQLITE3C) !IFNDEF SHELL_CORE_DEP !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 SHELL_CORE_DEP = $(SQLITE3DLL) +# <> +!ELSEIF $(USE_AMALGAMATION)==0 +SHELL_CORE_DEP = libsqlite3.lib +# <> !ELSE SHELL_CORE_DEP = !ENDIF !ENDIF +# <> +# If zlib support is enabled, add the dependencies for it. +# +!IF $(USE_ZLIB)!=0 && $(BUILD_ZLIB)!=0 +SHELL_CORE_DEP = zlib $(SHELL_CORE_DEP) +TESTFIXTURE_DEP = zlib $(TESTFIXTURE_DEP) +!ENDIF +# <> + # This is the core library that the shell executable should link with. # !IFNDEF SHELL_CORE_LIB !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 SHELL_CORE_LIB = $(SQLITE3LIB) +# <> +!ELSEIF $(USE_AMALGAMATION)==0 +SHELL_CORE_LIB = libsqlite3.lib +# <> !ELSE SHELL_CORE_LIB = !ENDIF @@ -802,12 +852,16 @@ RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1 # prior to running nmake in order to match the actual installed location and # version on this machine. # +!IFNDEF TCLDIR +TCLDIR = $(TOP)\compat\tcl +!ENDIF + !IFNDEF TCLINCDIR -TCLINCDIR = c:\tcl\include +TCLINCDIR = $(TCLDIR)\include !ENDIF !IFNDEF TCLLIBDIR -TCLLIBDIR = c:\tcl\lib +TCLLIBDIR = $(TCLDIR)\lib !ENDIF !IFNDEF LIBTCL @@ -819,7 +873,32 @@ LIBTCLSTUB = tclstub86.lib !ENDIF !IFNDEF LIBTCLPATH -LIBTCLPATH = c:\tcl\bin +LIBTCLPATH = $(TCLDIR)\bin +!ENDIF + +# The locations of the zlib header and library files. These variables +# (ZLIBINCDIR, ZLIBLIBDIR, and ZLIBLIB) may be overridden via the environment +# prior to running nmake in order to match the actual installed (or source +# code) location on this machine. +# +!IFNDEF ZLIBDIR +ZLIBDIR = $(TOP)\compat\zlib +!ENDIF + +!IFNDEF ZLIBINCDIR +ZLIBINCDIR = $(ZLIBDIR) +!ENDIF + +!IFNDEF ZLIBLIBDIR +ZLIBLIBDIR = $(ZLIBDIR) +!ENDIF + +!IFNDEF ZLIBLIB +!IF $(DYNAMIC_SHELL)!=0 +ZLIBLIB = zdll.lib +!ELSE +ZLIBLIB = zlib.lib +!ENDIF !ENDIF # The locations of the ICU header and library files. These variables @@ -827,12 +906,16 @@ LIBTCLPATH = c:\tcl\bin # prior to running nmake in order to match the actual installed location on # this machine. # +!IFNDEF ICUDIR +ICUDIR = $(TOP)\compat\icu +!ENDIF + !IFNDEF ICUINCDIR -ICUINCDIR = c:\icu\include +ICUINCDIR = $(ICUDIR)\include !ENDIF !IFNDEF ICULIBDIR -ICULIBDIR = c:\icu\lib +ICULIBDIR = $(ICUDIR)\lib !ENDIF !IFNDEF LIBICU @@ -845,7 +928,11 @@ LIBICU = icuuc.lib icuin.lib # specific Tcl shell to use. # !IFNDEF TCLSH_CMD +!IF $(USE_TCLSH_IN_PATH)!=0 || !EXIST("$(TCLDIR)\bin\tclsh.exe") TCLSH_CMD = tclsh +!ELSE +TCLSH_CMD = $(TCLDIR)\bin\tclsh.exe +!ENDIF !ENDIF # <> @@ -951,6 +1038,15 @@ BCC = $(BCC) -Zi !ENDIF # <> +# If zlib support is enabled, add the compiler options for it. +# +!IF $(USE_ZLIB)!=0 +TCC = $(TCC) -DSQLITE_HAVE_ZLIB=1 +RCC = $(RCC) -DSQLITE_HAVE_ZLIB=1 +TCC = $(TCC) -I$(ZLIBINCDIR) +RCC = $(RCC) -I$(ZLIBINCDIR) +!ENDIF + # If ICU support is enabled, add the compiler options for it. # !IF $(USE_ICU)!=0 @@ -974,7 +1070,7 @@ LTLINK = $(TCC) -Fe$@ # If requested, link to the RPCRT4 library. # !IF $(USE_RPCRT4_LIB)!=0 -LTLINK = $(LTLINK) rpcrt4.lib +LTLIBS = $(LTLIBS) rpcrt4.lib !ENDIF # If a platform was set, force the linker to target that. @@ -1071,8 +1167,15 @@ LDFLAGS = $(LDOPTS) # Start with the Tcl related linker options. # !IF $(NO_TCL)==0 -LTLIBPATHS = /LIBPATH:$(TCLLIBDIR) -LTLIBS = $(LIBTCL) +TCLLIBPATHS = $(TCLLIBPATHS) /LIBPATH:$(TCLLIBDIR) +TCLLIBS = $(TCLLIBS) $(LIBTCL) +!ENDIF + +# If zlib support is enabled, add the linker options for it. +# +!IF $(USE_ZLIB)!=0 +LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ZLIBLIBDIR) +LTLIBS = $(LTLIBS) $(ZLIBLIB) !ENDIF # If ICU support is enabled, add the linker options for it. @@ -1091,26 +1194,27 @@ LTLIBS = $(LTLIBS) $(LIBICU) # LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \ backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ - callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \ + callback.lo complete.lo ctime.lo \ + date.lo dbpage.lo dbstat.lo delete.lo \ expr.lo fault.lo fkey.lo \ fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \ fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \ fts3_tokenize_vtab.lo fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \ fts5.lo \ func.lo global.lo hash.lo \ - icu.lo insert.lo legacy.lo loadext.lo \ + icu.lo insert.lo json1.lo legacy.lo loadext.lo \ main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \ - memjournal.lo \ + memdb.lo memjournal.lo \ mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \ pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ random.lo resolve.lo rowset.lo rtree.lo \ - sqlite3session.lo select.lo sqlite3rbu.lo status.lo \ + sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \ table.lo threads.lo tokenize.lo treeview.lo trigger.lo \ - update.lo util.lo vacuum.lo \ + update.lo upsert.lo util.lo vacuum.lo \ vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \ - utf.lo vtab.lo + window.lo utf.lo vtab.lo # <> # Object files for the amalgamation. @@ -1154,6 +1258,7 @@ SRC00 = \ $(TOP)\src\complete.c \ $(TOP)\src\ctime.c \ $(TOP)\src\date.c \ + $(TOP)\src\dbpage.c \ $(TOP)\src\dbstat.c \ $(TOP)\src\delete.c \ $(TOP)\src\expr.c \ @@ -1172,6 +1277,7 @@ SRC00 = \ $(TOP)\src\mem2.c \ $(TOP)\src\mem3.c \ $(TOP)\src\mem5.c \ + $(TOP)\src\memdb.c \ $(TOP)\src\memjournal.c \ $(TOP)\src\mutex.c \ $(TOP)\src\mutex_noop.c \ @@ -1204,6 +1310,7 @@ SRC01 = \ $(TOP)\src\trigger.c \ $(TOP)\src\utf.c \ $(TOP)\src\update.c \ + $(TOP)\src\upsert.c \ $(TOP)\src\util.c \ $(TOP)\src\vacuum.c \ $(TOP)\src\vdbe.c \ @@ -1218,12 +1325,8 @@ SRC01 = \ $(TOP)\src\walker.c \ $(TOP)\src\where.c \ $(TOP)\src\wherecode.c \ - $(TOP)\src\whereexpr.c - -# Shell source code files. -# -SRC02 = \ - $(TOP)\src\shell.c + $(TOP)\src\whereexpr.c \ + $(TOP)\src\window.c # Core miscellaneous files. # @@ -1316,6 +1419,7 @@ SRC09 = \ $(TOP)\ext\fts3\fts3_tokenizer.h \ $(TOP)\ext\icu\sqliteicu.h \ $(TOP)\ext\rtree\rtree.h \ + $(TOP)\ext\rtree\geopoly.c \ $(TOP)\ext\rbu\sqlite3rbu.h \ $(TOP)\ext\session\sqlite3session.h @@ -1331,6 +1435,7 @@ SRC11 = \ keywordhash.h \ opcodes.h \ parse.h \ + shell.c \ $(SQLITE3H) # Generated Tcl header files @@ -1345,7 +1450,7 @@ SRC12 = # All source code files. # -SRC = $(SRC00) $(SRC01) $(SRC02) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11) +SRC = $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11) # Source code to the test files. # @@ -1376,6 +1481,7 @@ TESTSRC = \ $(TOP)\src\test_intarray.c \ $(TOP)\src\test_journal.c \ $(TOP)\src\test_malloc.c \ + $(TOP)\src\test_md5.c \ $(TOP)\src\test_multiplex.c \ $(TOP)\src\test_mutex.c \ $(TOP)\src\test_onefile.c \ @@ -1387,10 +1493,12 @@ TESTSRC = \ $(TOP)\src\test_server.c \ $(TOP)\src\test_superlock.c \ $(TOP)\src\test_syscall.c \ + $(TOP)\src\test_tclsh.c \ $(TOP)\src\test_tclvar.c \ $(TOP)\src\test_thread.c \ $(TOP)\src\test_vfs.c \ $(TOP)\src\test_windirent.c \ + $(TOP)\src\test_window.c \ $(TOP)\src\test_wsd.c \ $(TOP)\ext\fts3\fts3_term.c \ $(TOP)\ext\fts3\fts3_test.c \ @@ -1400,18 +1508,23 @@ TESTSRC = \ # Statically linked extensions. # TESTEXT = \ + $(TOP)\ext\expert\sqlite3expert.c \ + $(TOP)\ext\expert\test_expert.c \ $(TOP)\ext\misc\amatch.c \ $(TOP)\ext\misc\carray.c \ $(TOP)\ext\misc\closure.c \ $(TOP)\ext\misc\csv.c \ $(TOP)\ext\misc\eval.c \ + $(TOP)\ext\misc\explain.c \ $(TOP)\ext\misc\fileio.c \ $(TOP)\ext\misc\fuzzer.c \ $(TOP)\ext\fts5\fts5_tcl.c \ $(TOP)\ext\fts5\fts5_test_mi.c \ $(TOP)\ext\fts5\fts5_test_tok.c \ $(TOP)\ext\misc\ieee754.c \ + $(TOP)\ext\misc\mmapwarm.c \ $(TOP)\ext\misc\nextchar.c \ + $(TOP)\ext\misc\normalize.c \ $(TOP)\ext\misc\percentile.c \ $(TOP)\ext\misc\regexp.c \ $(TOP)\ext\misc\remember.c \ @@ -1421,6 +1534,12 @@ TESTEXT = \ $(TOP)\ext\misc\unionvtab.c \ $(TOP)\ext\misc\wholenumber.c +# If use of zlib is enabled, add the "zipfile.c" source file. +# +!IF $(USE_ZLIB)!=0 +TESTEXT = $(TESTEXT) $(TOP)\ext\misc\zipfile.c +!ENDIF + # Source code to the library files needed by the test fixture # (non-amalgamation) # @@ -1476,7 +1595,8 @@ EXTHDR = $(EXTHDR) \ $(TOP)\ext\fts3\fts3_hash.h \ $(TOP)\ext\fts3\fts3_tokenizer.h EXTHDR = $(EXTHDR) \ - $(TOP)\ext\rtree\rtree.h + $(TOP)\ext\rtree\rtree.h \ + $(TOP)\ext\rtree\geopoly.c EXTHDR = $(EXTHDR) \ $(TOP)\ext\icu\sqliteicu.h EXTHDR = $(EXTHDR) \ @@ -1490,8 +1610,10 @@ TESTPROGS = \ testfixture.exe \ $(SQLITE3EXE) \ sqlite3_analyzer.exe \ + sqlite3_checker.exe \ sqldiff.exe \ - dbhash.exe + dbhash.exe \ + sqltclsh.exe # Databases containing fuzzer test cases # @@ -1500,27 +1622,29 @@ FUZZDATA = \ $(TOP)\test\fuzzdata2.db \ $(TOP)\test\fuzzdata3.db \ $(TOP)\test\fuzzdata4.db \ - $(TOP)\test\fuzzdata5.db + $(TOP)\test\fuzzdata5.db \ + $(TOP)\test\fuzzdata6.db # <> # Additional compiler options for the shell. These are only effective # when the shell is not being dynamically linked. # !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0 -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1 !ENDIF # <> # Extra compiler options for various test tools. # -MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5 +MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 +FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000 FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ -DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 # Standard options to testfixture. @@ -1539,7 +1663,15 @@ ALL_TCL_TARGETS = # 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 shell $(ALL_TCL_TARGETS) +core: dll libsqlite3.lib shell + +# Targets that require the Tcl library. +# +tcl: $(ALL_TCL_TARGETS) + +# This Makefile target builds all of the standard binaries. +# +all: core tcl # Dynamic link library section. # @@ -1564,12 +1696,12 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) sqlite3.def: libsqlite3.lib echo EXPORTS > sqlite3.def dumpbin /all libsqlite3.lib \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup)?_[^@]*)(?:@\d+)?$$" \1 \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@]*)(?:@\d+)?$$" \1 \ | sort >> sqlite3.def # <> -$(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) - $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \ +$(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) + $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \ /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) # <> @@ -1580,13 +1712,13 @@ dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + $(LTLINK) $(NO_WARN) -DSCRUB_STANDALONE=1 $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) srcck1.exe: $(TOP)\tool\srcck1.c $(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c -sourcetest: srcck1.exe sqlite3.c - srcck1.exe sqlite3.c +sourcetest: srcck1.exe $(SQLITE3C) + srcck1.exe $(SQLITE3C) fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -1600,6 +1732,9 @@ fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H) ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +sessionfuzz.exe: zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB) + mptester.exe: $(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -1628,7 +1763,6 @@ mptest: mptester.exe -mkdir tsrc for %i in ($(SRC00)) do copy /Y %i tsrc for %i in ($(SRC01)) do copy /Y %i tsrc - for %i in ($(SRC02)) do copy /Y %i tsrc for %i in ($(SRC03)) do copy /Y %i tsrc for %i in ($(SRC04)) do copy /Y %i tsrc for %i in ($(SRC05)) do copy /Y %i tsrc @@ -1648,7 +1782,6 @@ mptest: mptester.exe sqlite3.c: .target_source sqlite3ext.h $(MKSQLITE3C_TOOL) $(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS) - copy tsrc\shell.c . copy $(TOP)\ext\session\sqlite3session.h . sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl @@ -1670,6 +1803,12 @@ lemon.exe: $(TOP)\tool\lemon.c lempar.c $(BCC) $(NO_WARN) -Daccess=_access \ -Fe$@ $(TOP)\tool\lemon.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS) +# <> +# Rules to build the source-id generator tool +# +mksourceid.exe: $(TOP)\tool\mksourceid.c + $(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\mksourceid.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS) + # Rules to build individual *.lo files from generated *.c files. This # applies to: # @@ -1740,7 +1879,10 @@ ctime.lo: $(TOP)\src\ctime.c $(HDR) date.lo: $(TOP)\src\date.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c -dbstat.lo: $(TOP)\src\date.c $(HDR) +dbpage.lo: $(TOP)\src\dbpage.c $(HDR) + $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbpage.c + +dbstat.lo: $(TOP)\src\dbstat.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbstat.c delete.lo: $(TOP)\src\delete.c $(HDR) @@ -1794,6 +1936,9 @@ mem3.lo: $(TOP)\src\mem3.c $(HDR) mem5.lo: $(TOP)\src\mem5.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\mem5.c +memdb.lo: $(TOP)\src\memdb.c $(HDR) + $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memdb.c + memjournal.lo: $(TOP)\src\memjournal.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memjournal.c @@ -1872,6 +2017,9 @@ trigger.lo: $(TOP)\src\trigger.c $(HDR) update.lo: $(TOP)\src\update.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\update.c +upsert.lo: $(TOP)\src\upsert.c $(HDR) + $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\upsert.c + utf.lo: $(TOP)\src\utf.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\utf.c @@ -1920,14 +2068,17 @@ wherecode.lo: $(TOP)\src\wherecode.c $(HDR) whereexpr.lo: $(TOP)\src\whereexpr.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c +window.lo: $(TOP)\src\window.c $(HDR) + $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\window.c + tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP) $(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP) - $(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c + $(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) - $(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS) + $(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) # Rules to build opcodes.c and opcodes.h # @@ -1948,7 +2099,7 @@ parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl move parse.h parse.h.temp $(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h -$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION +$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS) sqlite3ext.h: .target_source @@ -1967,7 +2118,29 @@ mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe .\mkkeywordhash.exe > keywordhash.h +# Source files that go into making shell.c +SHELL_SRC = \ + $(TOP)\src\shell.c.in \ + $(TOP)\ext\misc\appendvfs.c \ + $(TOP)\ext\misc\shathree.c \ + $(TOP)\ext\misc\fileio.c \ + $(TOP)\ext\misc\completion.c \ + $(TOP)\ext\expert\sqlite3expert.c \ + $(TOP)\ext\expert\sqlite3expert.h \ + $(TOP)\src\test_windirent.c +# If use of zlib is enabled, add the "zipfile.c" source file. +# +!IF $(USE_ZLIB)!=0 +SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\sqlar.c +SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\zipfile.c +!ENDIF + +shell.c: $(SHELL_SRC) $(TOP)\tool\mkshellc.tcl + $(TCLSH_CMD) $(TOP)\tool\mkshellc.tcl > shell.c + +zlib: + pushd $(ZLIBDIR) && $(MAKE) /f win32\Makefile.msc clean $(ZLIBLIB) && popd # Rules to build the extension objects. # @@ -2031,6 +2204,12 @@ fts3_unicode2.lo: $(TOP)\ext\fts3\fts3_unicode2.c $(HDR) $(EXTHDR) fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c +json1.lo: $(TOP)\ext\misc\json1.c $(HDR) $(EXTHDR) + $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\misc\json1.c + +stmt.lo: $(TOP)\ext\misc\stmt.c $(HDR) $(EXTHDR) + $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\misc\stmt.c + rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c @@ -2056,6 +2235,24 @@ FTS5_SRC = \ $(TOP)\ext\fts5\fts5_varint.c \ $(TOP)\ext\fts5\fts5_vocab.c +LSM1_SRC = \ + $(TOP)\ext\lsm1\lsm.h \ + $(TOP)\ext\lsm1\lsmInt.h \ + $(TOP)\ext\lsm1\lsm_ckpt.c \ + $(TOP)\ext\lsm1\lsm_file.c \ + $(TOP)\ext\lsm1\lsm_log.c \ + $(TOP)\ext\lsm1\lsm_main.c \ + $(TOP)\ext\lsm1\lsm_mem.c \ + $(TOP)\ext\lsm1\lsm_mutex.c \ + $(TOP)\ext\lsm1\lsm_shared.c \ + $(TOP)\ext\lsm1\lsm_sorted.c \ + $(TOP)\ext\lsm1\lsm_str.c \ + $(TOP)\ext\lsm1\lsm_tree.c \ + $(TOP)\ext\lsm1\lsm_unix.c \ + $(TOP)\ext\lsm1\lsm_varint.c \ + $(TOP)\ext\lsm1\lsm_vtab.c \ + $(TOP)\ext\lsm1\lsm_win32.c + fts5parse.c: $(TOP)\ext\fts5\fts5parse.y lemon.exe copy $(TOP)\ext\fts5\fts5parse.y . del /Q fts5parse.h 2>NUL @@ -2067,6 +2264,10 @@ fts5.c: $(FTS5_SRC) $(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl copy $(TOP)\ext\fts5\fts5.h . +lsm1.c: $(LSM1_SRC) + $(TCLSH_CMD) $(TOP)\ext\lsm1\tool\mklsm1c.tcl + copy $(TOP)\ext\lsm1\lsm.h . + fts5.lo: fts5.c $(HDR) $(EXTHDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c fts5.c @@ -2086,12 +2287,14 @@ sqlite3rbu.lo: $(TOP)\ext\rbu\sqlite3rbu.c $(HDR) $(EXTHDR) # necessary because the test fixture requires non-API symbols which are # hidden when the library is built via the amalgamation). # -TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 +TESTFIXTURE_FLAGS = -DTCLSH_INIT_PROC=sqlite3TestInit -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN) TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024 -TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS) TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) @@ -2122,11 +2325,11 @@ sqlite_tcl.h: | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*createProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *createProc)" >> $(SQLITETCLH) !ENDIF -testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP) +testfixture.exe: $(TESTFIXTURE_SRC) $(TESTFIXTURE_DEP) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ - /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) + /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) extensiontest: testfixture.exe testloadext.dll @set PATH=$(LIBTCLPATH);$(PATH) @@ -2171,24 +2374,45 @@ smoketest: $(TESTPROGS) @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\main.test $(TESTOPTS) -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(SQLITE_TCL_DEP) - 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){ >> $@ - echo static const char *zMainloop = >> $@ - $(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@ - echo ; return zMainloop; } >> $@ +sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(SQLITE_TCL_DEP) + $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) $(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \ - /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) + /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) -dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) +sqltclsh.c: sqlite3.c $(TOP)\src\tclsqlite.c $(TOP)\tool\sqltclsh.tcl $(TOP)\ext\misc\appendvfs.c $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in + $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in >sqltclsh.c + +sqltclsh.exe: sqltclsh.c $(SHELL_CORE_DEP) $(LIBRESOBJS) + $(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqltclsh.c \ + /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) + +sqlite3_expert.exe: $(SQLITE3C) $(TOP)\ext\expert\sqlite3expert.h $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c + $(LTLINK) $(NO_WARN) $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(SQLITE3C) $(TLIBS) + +CHECKER_DEPS =\ + $(TOP)/tool/mkccode.tcl \ + sqlite3.c \ + $(TOP)/src/tclsqlite.c \ + $(TOP)/ext/repair/sqlite3_checker.tcl \ + $(TOP)/ext/repair/checkindex.c \ + $(TOP)/ext/repair/checkfreelist.c \ + $(TOP)/ext/misc/btreeinfo.c \ + $(TOP)/ext/repair/sqlite3_checker.c.in + +sqlite3_checker.c: $(CHECKER_DEPS) + $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\ext\repair\sqlite3_checker.c.in > $@ + +sqlite3_checker.exe: sqlite3_checker.c $(LIBRESOBJS) + $(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_checker.c \ + /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) + +dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) $(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \ /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) -testloadext.lo: $(TOP)\src\test_loadext.c +testloadext.lo: $(TOP)\src\test_loadext.c $(SQLITE3H) $(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c testloadext.dll: testloadext.lo @@ -2210,6 +2434,9 @@ showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +showshm.exe: $(TOP)\tool\showshm.c + $(LTLINK) $(NO_WARN) $(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS) + changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \ @@ -2223,6 +2450,10 @@ rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +atrc.exe: $(TOP)\test\atrc.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ + $(TOP)\test\atrc.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS) @@ -2238,9 +2469,6 @@ kvtest.exe: $(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \ $(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) -dbselftest.exe: $(TOP)\test\dbselftest.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) $(DBSELFTEST_COMPILE_OPTS) $(TOP)\test\dbselftest.c $(SQLITE3C) - rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -2257,10 +2485,9 @@ clean: del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL # <> - del /Q sqlite3.c sqlite3.h 2>NUL del /Q opcodes.c opcodes.h 2>NUL del /Q lemon.* lempar.c parse.* 2>NUL - del /Q mkkeywordhash.* keywordhash.h 2>NUL + del /Q mksourceid.* mkkeywordhash.* keywordhash.h 2>NUL del /Q notasharedlib.* 2>NUL -rmdir /Q/S .deps 2>NUL -rmdir /Q/S .libs 2>NUL @@ -2274,11 +2501,16 @@ clean: del /Q changeset.exe 2>NUL del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL - del /Q sqlite3.c sqlite3-*.c 2>NUL + del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL del /Q sqlite3rc.h 2>NUL del /Q shell.c sqlite3ext.h sqlite3session.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 dbhash.exe 2>NUL + del /Q sqltclsh.* 2>NUL + del /Q dbfuzz.exe sessionfuzz.exe 2>NUL + del /Q kvtest.exe ossshell.exe scrub.exe 2>NUL + del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL del /Q fts5.* fts5parse.* 2>NUL + del /Q lsm.h lsm1.c 2>NUL # <> diff --git a/README.md b/README.md index a7b8701106..87f1f81103 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@

SQLite Source Repository

-This repository contains the complete source code for the SQLite database -engine. Some test scripts are also include. However, many other test scripts +This repository contains the complete source code for the +[SQLite database engine](https://sqlite.org/). Some test scripts +are also included. However, many other test scripts and most of the documentation are managed separately. -If you are reading this on a Git mirror someplace, you are doing it wrong. -The [official repository](https://www.sqlite.org/src/) is better. Go there -now. +SQLite [does not use Git](https://sqlite.org/whynotgit.html). +If you are reading this on GitHub, then you are looking at an +unofficial mirror. See for the official +repository. ## Obtaining The Code @@ -14,15 +16,17 @@ SQLite sources are managed using the [Fossil](https://www.fossil-scm.org/), a distributed version control system that was specifically designed to support SQLite development. If you do not want to use Fossil, you can download tarballs or ZIP -archives as follows: +archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows: - * Lastest trunk check-in: - or - . + * Lastest trunk check-in as + [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz), + [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or + [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar). - * Latest release: - or - . + * Latest release as + [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release), + [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or + [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release). * For other check-ins, substitute an appropriate branch name or tag or hash prefix for "release" in the URLs of the previous @@ -104,7 +108,6 @@ recommended. SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation is required by the makefiles (including those for MSVC). SQLite contains a lot of generated code and Tcl is used to do much of that code generation. -The makefiles also require AWK. ## Source Code Tour @@ -116,7 +119,7 @@ The **src/** also contains the "shell.c" file which is the main program for the "sqlite3.exe" [command-line shell](https://sqlite.org/cli.html) and the "tclsqlite.c" file which implements the -[TCL bindings](https://sqlite.org/tclsqlite.html) for SQLite. +[Tcl bindings](https://sqlite.org/tclsqlite.html) for SQLite. (Historical note: SQLite began as a Tcl extension and only later escaped to the wild as an independent library.) @@ -163,14 +166,14 @@ template for generating its parser. Lemon also generates the **parse.h** header file, at the same time it generates parse.c. But the parse.h header file is -modified further (to add additional symbols) using the ./addopcodes.awk -AWK script. +modified further (to add additional symbols) using the ./addopcodes.tcl +Tcl script. The **opcodes.h** header file contains macros that define the numbers corresponding to opcodes in the "VDBE" virtual machine. The opcodes.h file is generated by the scanning the src/vdbe.c source file. The -AWK script at ./mkopcodeh.awk does this scan and generates opcodes.h. -A second AWK script, ./mkopcodec.awk, then scans opcodes.h to generate +Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h. +A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate the **opcodes.c** source file, which contains a reverse mapping from opcode-number to opcode-name that is used for EXPLAIN output. @@ -207,8 +210,8 @@ The amalgamation source file is more than 200K lines long. Some symbolic debuggers (most notably MSVC) are unable to deal with files longer than 64K lines. To work around this, a separate Tcl script, tool/split-sqlite3c.tcl, can be run on the amalgamation to break it up into a single small C file -called **sqlite3-all.c** that does #include on about five other files -named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-5.c**. In this way, +called **sqlite3-all.c** that does #include on about seven other files +named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-7.c**. In this way, all of the source code is contained within a single translation unit so that the compiler can do extra cross-procedure optimization, but no individual source file exceeds 32K lines in length. @@ -237,7 +240,8 @@ Key files: trying to understand how the library works internally. * **sqliteInt.h** - this header file defines many of the data objects - used internally by SQLite. + used internally by SQLite. In addition to "sqliteInt.h", some + subsystems have their own header files. * **parse.y** - This file describes the LALR(1) grammar that SQLite uses to parse SQL statements, and the actions that are taken at each step @@ -249,29 +253,44 @@ Key files: which defines internal data objects. The rest of SQLite interacts with the VDBE through an interface defined by vdbe.h. - * **where.c** - This file analyzes the WHERE clause and generates + * **where.c** - This file (together with its helper files named + by "where*.c") analyzes the WHERE clause and generates virtual machine code to run queries efficiently. This file is sometimes called the "query optimizer". It has its own private header file, whereInt.h, that defines data objects used internally. * **btree.c** - This file contains the implementation of the B-Tree - storage engine used by SQLite. + storage engine used by SQLite. The interface to the rest of the system + is defined by "btree.h". The "btreeInt.h" header defines objects + used internally by btree.c and not published to the rest of the system. * **pager.c** - This file contains the "pager" implementation, the - module that implements transactions. + module that implements transactions. The "pager.h" header file + defines the interface between pager.c and the rest of the system. * **os_unix.c** and **os_win.c** - These two files implement the interface between SQLite and the underlying operating system using the run-time pluggable VFS interface. - * **shell.c** - This file is not part of the core SQLite library. This + * **shell.c.in** - This file is not part of the core SQLite library. This is the file that, when linked against sqlite3.a, generates the - "sqlite3.exe" command-line shell. + "sqlite3.exe" command-line shell. The "shell.c.in" file is transformed + into "shell.c" as part of the build process. * **tclsqlite.c** - This file implements the Tcl bindings for SQLite. It is not part of the core SQLite library. But as most of the tests in this repository are written in Tcl, the Tcl language bindings are important. + * **test*.c** - Files in the src/ folder that begin with "test" go into + building the "testfixture.exe" program. The testfixture.exe program is + an enhanced Tcl shell. The testfixture.exe program runs scripts in the + test/ folder to validate the core SQLite code. The testfixture program + (and some other test programs too) is build and run when you type + "make test". + + * **ext/misc/json1.c** - This file implements the various JSON functions + that are build into SQLite. + There are many other source files. Each has a succinct header comment that describes its purpose and role within the larger system. diff --git a/VERSION b/VERSION index 6075c9a9ff..419ede3b9c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.21.0 +3.26.0 diff --git a/autoconf/Makefile.am b/autoconf/Makefile.am index e8211596d9..20af7433be 100644 --- a/autoconf/Makefile.am +++ b/autoconf/Makefile.am @@ -1,6 +1,5 @@ -AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE - +AM_CFLAGS = @BUILD_CFLAGS@ lib_LTLIBRARIES = libsqlite3.la libsqlite3_la_SOURCES = sqlite3.c libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8 @@ -10,11 +9,11 @@ sqlite3_SOURCES = shell.c sqlite3.h EXTRA_sqlite3_SOURCES = sqlite3.c sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@ sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@ -sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS +sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS) include_HEADERS = sqlite3.h sqlite3ext.h -EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs +EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback pkgconfigdir = ${libdir}/pkgconfig pkgconfig_DATA = sqlite3.pc diff --git a/autoconf/Makefile.fallback b/autoconf/Makefile.fallback new file mode 100644 index 0000000000..9355b147a8 --- /dev/null +++ b/autoconf/Makefile.fallback @@ -0,0 +1,19 @@ +#!/usr/bin/make +# +# If the configure script does not work, then this Makefile is available +# as a backup. Manually configure the variables below. +# +# Note: This makefile works out-of-the-box on MacOS 10.2 (Jaguar) +# +CC = gcc +CFLAGS = -O0 -I. +LIBS = -lz +COPTS += -D_BSD_SOURCE +COPTS += -DSQLITE_ENABLE_LOCKING_STYLE=0 +COPTS += -DSQLITE_THREADSAFE=0 +COPTS += -DSQLITE_OMIT_LOAD_EXTENSION +COPTS += -DSQLITE_WITHOUT_ZONEMALLOC +COPTS += -DSQLITE_ENABLE_RTREE + +sqlite3: shell.c sqlite3.c + $(CC) $(CFLAGS) $(COPTS) -o sqlite3 shell.c sqlite3.c $(LIBS) diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index f0f9a01ee0..270c83c230 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -277,6 +277,12 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb !IF $(MINIMAL_AMALGAMATION)==0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1 !ENDIF OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 !ENDIF @@ -561,6 +567,7 @@ SHELL_CORE_DEP = !ENDIF !ENDIF + # This is the core library that the shell executable should link with. # !IFNDEF SHELL_CORE_LIB @@ -808,7 +815,7 @@ LTLINK = $(TCC) -Fe$@ # If requested, link to the RPCRT4 library. # !IF $(USE_RPCRT4_LIB)!=0 -LTLINK = $(LTLINK) rpcrt4.lib +LTLIBS = $(LTLIBS) rpcrt4.lib !ENDIF # If a platform was set, force the linker to target that. @@ -927,14 +934,24 @@ LIBRESOBJS = # when the shell is not being dynamically linked. # !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0 -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1 !ENDIF # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # -all: dll shell +core: dll shell + +# Targets that require the Tcl library. +# +tcl: $(ALL_TCL_TARGETS) + +# This Makefile target builds all of the standard binaries. +# +all: core tcl # Dynamic link library section. # @@ -954,11 +971,11 @@ Replace.exe: sqlite3.def: Replace.exe $(LIBOBJ) echo EXPORTS > sqlite3.def dumpbin /all $(LIBOBJ) \ - | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ + | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ | sort >> sqlite3.def -$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) - $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \ +$(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) + $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \ /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) @@ -973,7 +990,7 @@ sqlite3.lo: $(SQLITE3C) !IF $(USE_RC)!=0 _HASHCHAR=^# !IF ![echo !IFNDEF VERSION > rcver.vc] && \ - ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \ + ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| "%SystemRoot%\System32\find.exe" "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \ ![echo !ENDIF >> rcver.vc] !INCLUDE rcver.vc !ENDIF diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 5a607de054..82ab43dfa8 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -12,6 +12,7 @@ AC_PREREQ(2.61) AC_INIT(sqlite, --SQLITE-VERSION--, http://www.sqlite.org) AC_CONFIG_SRCDIR([sqlite3.c]) +AC_CONFIG_AUX_DIR([.]) # Use automake. AM_INIT_AUTOMAKE([foreign]) @@ -28,6 +29,7 @@ AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r]) AC_FUNC_STRERROR_R AC_CONFIG_FILES([Makefile sqlite3.pc]) +BUILD_CFLAGS= AC_SUBST(BUILD_CFLAGS) #------------------------------------------------------------------------- @@ -85,13 +87,11 @@ AC_SUBST(READLINE_LIBS) AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING( [--enable-threadsafe], [build a thread-safe library [default=yes]])], [], [enable_threadsafe=yes]) -THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0 if test x"$enable_threadsafe" != "xno"; then - THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1" + BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1" AC_SEARCH_LIBS(pthread_create, pthread) AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) fi -AC_SUBST(THREADSAFE_FLAGS) #----------------------------------------------------------------------- #----------------------------------------------------------------------- @@ -103,36 +103,66 @@ AC_ARG_ENABLE(dynamic-extensions, [AS_HELP_STRING( if test x"$enable_dynamic_extensions" != "xno"; then AC_SEARCH_LIBS(dlopen, dl) else - DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1 + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1" fi AC_MSG_CHECKING([for whether to support dynamic extensions]) AC_MSG_RESULT($enable_dynamic_extensions) -AC_SUBST(DYNAMIC_EXTENSION_FLAGS) +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# --enable-fts4 +# +AC_ARG_ENABLE(fts4, [AS_HELP_STRING( + [--enable-fts4], [include fts4 support [default=yes]])], + [], [enable_fts4=yes]) +if test x"$enable_fts4" = "xyes"; then + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4" +fi +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# --enable-fts3 +# +AC_ARG_ENABLE(fts3, [AS_HELP_STRING( + [--enable-fts3], [include fts3 support [default=no]])], + [], []) +if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3" +fi #----------------------------------------------------------------------- #----------------------------------------------------------------------- # --enable-fts5 # AC_ARG_ENABLE(fts5, [AS_HELP_STRING( - [--enable-fts5], [include fts5 support [default=no]])], - [], [enable_fts5=no]) + [--enable-fts5], [include fts5 support [default=yes]])], + [], [enable_fts5=yes]) if test x"$enable_fts5" = "xyes"; then AC_SEARCH_LIBS(log, m) - FTS5_FLAGS=-DSQLITE_ENABLE_FTS5 + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5" fi -AC_SUBST(FTS5_FLAGS) #----------------------------------------------------------------------- #----------------------------------------------------------------------- # --enable-json1 # AC_ARG_ENABLE(json1, [AS_HELP_STRING( - [--enable-json1], [include json1 support [default=no]])], - [], [enable_json1=no]) + [--enable-json1], [include json1 support [default=yes]])], + [],[enable_json1=yes]) if test x"$enable_json1" = "xyes"; then - JSON1_FLAGS=-DSQLITE_ENABLE_JSON1 + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1" +fi +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# --enable-rtree +# +AC_ARG_ENABLE(rtree, [AS_HELP_STRING( + [--enable-rtree], [include rtree support [default=yes]])], + [], [enable_rtree=yes]) +if test x"$enable_rtree" = "xyes"; then + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE" fi -AC_SUBST(JSON1_FLAGS) #----------------------------------------------------------------------- #----------------------------------------------------------------------- @@ -140,11 +170,22 @@ AC_SUBST(JSON1_FLAGS) # AC_ARG_ENABLE(session, [AS_HELP_STRING( [--enable-session], [enable the session extension [default=no]])], - [], [enable_session=no]) + [], []) if test x"$enable_session" = "xyes"; then - SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" +fi +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# --enable-debug +# +AC_ARG_ENABLE(debug, [AS_HELP_STRING( + [--enable-debug], [build with debugging features enabled [default=no]])], + [], []) +if test x"$enable_debug" = "xyes"; then + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" + CFLAGS="-g -O0" fi -AC_SUBST(SESSION_FLAGS) #----------------------------------------------------------------------- #----------------------------------------------------------------------- @@ -163,6 +204,12 @@ AC_SUBST(EXTRA_SHELL_OBJ) #----------------------------------------------------------------------- AC_CHECK_FUNCS(posix_fallocate) +AC_CHECK_HEADERS(zlib.h,[ + AC_SEARCH_LIBS(deflate,z,[BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"]) +]) + +AC_SEARCH_LIBS(system,,,[SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"]) +AC_SUBST(SHELL_CFLAGS) #----------------------------------------------------------------------- # UPDATE: Maybe it's better if users just set CFLAGS before invoking diff --git a/configure b/configure index 7a81d52156..51653aa599 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.21.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.26.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.21.0' -PACKAGE_STRING='sqlite 3.21.0' +PACKAGE_VERSION='3.26.0' +PACKAGE_STRING='sqlite 3.26.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -772,6 +772,7 @@ LIBOBJS BUILD_CFLAGS USE_GCOV OPT_FEATURE_FLAGS +HAVE_ZLIB USE_AMALGAMATION TARGET_DEBUG TARGET_HAVE_EDITLINE @@ -909,6 +910,8 @@ enable_fts3 enable_fts4 enable_fts5 enable_json1 +enable_update_limit +enable_geopoly enable_rtree enable_session enable_gcov @@ -1463,7 +1466,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.21.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1528,7 +1531,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.21.0:";; + short | recursive ) echo "Configuration of sqlite 3.26.0:";; esac cat <<\_ACEOF @@ -1560,6 +1563,8 @@ Optional Features: --enable-fts4 Enable the FTS4 extension --enable-fts5 Enable the FTS5 extension --enable-json1 Enable the JSON1 extension + --enable-update-limit Enable the UPDATE/DELETE LIMIT clause + --enable-geopoly Enable the GEOPOLY extension --enable-rtree Enable the RTREE extension --enable-session Enable the SESSION extension --enable-gcov Enable coverage testing using gcov @@ -1652,7 +1657,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.21.0 +sqlite configure 3.26.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2071,7 +2076,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.21.0, which was +It was created by sqlite $as_me 3.26.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3929,13 +3934,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3932: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3937: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3935: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3940: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3938: output\"" >&5) + (eval echo "\"\$as_me:3943: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5141,7 +5146,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5144 "configure"' > conftest.$ac_ext + echo '#line 5149 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6666,11 +6671,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6669: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6674: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6673: \$? = $ac_status" >&5 + echo "$as_me:6678: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7005,11 +7010,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7008: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7013: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7012: \$? = $ac_status" >&5 + echo "$as_me:7017: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7110,11 +7115,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7113: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7118: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7117: \$? = $ac_status" >&5 + echo "$as_me:7122: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7165,11 +7170,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7168: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7173: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7172: \$? = $ac_status" >&5 + echo "$as_me:7177: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9545,7 +9550,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9548 "configure" +#line 9553 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9641,7 +9646,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9644 "configure" +#line 9649 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10302,7 +10307,7 @@ USE_AMALGAMATION=1 # if not, then we fall back to plain tclsh. # TODO: try other versions before falling back? # -for ac_prog in tclsh8.6 tclsh8.5 tclsh +for ac_prog in tclsh8.7 tclsh8.6 tclsh8.5 tclsh do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -10452,8 +10457,6 @@ fi # Check whether --enable-threadsafe was given. if test "${enable_threadsafe+set}" = set; then : enableval=$enable_threadsafe; -else - enable_threadsafe=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support threadsafe operation" >&5 @@ -11246,12 +11249,10 @@ fi # check for debug enabled # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; use_debug=$enableval -else - use_debug=no + enableval=$enable_debug; fi -if test "${use_debug}" = "yes" ; then +if test "${enable_debug}" = "yes" ; then TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" else TARGET_DEBUG="-DNDEBUG" @@ -11262,26 +11263,98 @@ fi # See whether we should use the amalgamation to build # Check whether --enable-amalgamation was given. if test "${enable_amalgamation+set}" = set; then : - enableval=$enable_amalgamation; use_amalgamation=$enableval -else - use_amalgamation=yes + enableval=$enable_amalgamation; fi -if test "${use_amalgamation}" != "yes" ; then +if test "${enable_amalgamation}" == "no" ; then USE_AMALGAMATION=0 fi +######### +# Look for zlib. Only needed by extensions and by the sqlite3.exe shell +for ac_header in zlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ZLIB_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5 +$as_echo_n "checking for library containing deflate... " >&6; } +if ${ac_cv_search_deflate+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char deflate (); +int +main () +{ +return deflate (); + ; + return 0; +} +_ACEOF +for ac_lib in '' z; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_deflate=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_deflate+:} false; then : + break +fi +done +if ${ac_cv_search_deflate+:} false; then : + +else + ac_cv_search_deflate=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5 +$as_echo "$ac_cv_search_deflate" >&6; } +ac_res=$ac_cv_search_deflate +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + HAVE_ZLIB="-DSQLITE_HAVE_ZLIB=1" +else + HAVE_ZLIB="" +fi + + + ######### # See whether we should allow loadable extensions # Check whether --enable-load-extension was given. if test "${enable_load_extension+set}" = set; then : - enableval=$enable_load_extension; use_loadextension=$enableval + enableval=$enable_load_extension; else - use_loadextension=yes + enable_load_extension=yes fi -if test "${use_loadextension}" = "yes" ; then +if test "${enable_load_extension}" = "yes" ; then OPT_FEATURE_FLAGS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } @@ -11348,9 +11421,7 @@ fi # # Check whether --enable-memsys5 was given. if test "${enable_memsys5+set}" = set; then : - enableval=$enable_memsys5; enable_memsys5=yes -else - enable_memsys5=no + enableval=$enable_memsys5; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5 @@ -11365,9 +11436,7 @@ $as_echo "no" >&6; } fi # Check whether --enable-memsys3 was given. if test "${enable_memsys3+set}" = set; then : - enableval=$enable_memsys3; enable_memsys3=yes -else - enable_memsys3=no + enableval=$enable_memsys3; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 @@ -11385,9 +11454,7 @@ fi # See whether we should enable Full Text Search extensions # Check whether --enable-fts3 was given. if test "${enable_fts3+set}" = set; then : - enableval=$enable_fts3; enable_fts3=yes -else - enable_fts3=no + enableval=$enable_fts3; fi if test "${enable_fts3}" = "yes" ; then @@ -11395,9 +11462,7 @@ if test "${enable_fts3}" = "yes" ; then fi # Check whether --enable-fts4 was given. if test "${enable_fts4+set}" = set; then : - enableval=$enable_fts4; enable_fts4=yes -else - enable_fts4=no + enableval=$enable_fts4; fi if test "${enable_fts4}" = "yes" ; then @@ -11461,9 +11526,7 @@ fi fi # Check whether --enable-fts5 was given. if test "${enable_fts5+set}" = set; then : - enableval=$enable_fts5; enable_fts5=yes -else - enable_fts5=no + enableval=$enable_fts5; fi if test "${enable_fts5}" = "yes" ; then @@ -11530,22 +11593,44 @@ fi # See whether we should enable JSON1 # Check whether --enable-json1 was given. if test "${enable_json1+set}" = set; then : - enableval=$enable_json1; enable_json1=yes -else - enable_json1=no + enableval=$enable_json1; fi if test "${enable_json1}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" fi +######### +# See whether we should enable the LIMIT clause on UPDATE and DELETE +# statements. +# Check whether --enable-update-limit was given. +if test "${enable_update_limit+set}" = set; then : + enableval=$enable_update_limit; +fi + +if test "${enable_udlimit}" = "yes" ; then + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" +fi + +######### +# See whether we should enable GEOPOLY +# Check whether --enable-geopoly was given. +if test "${enable_geopoly+set}" = set; then : + enableval=$enable_geopoly; enable_geopoly=yes +else + enable_geopoly=no +fi + +if test "${enable_geopoly}" = "yes" ; then + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" + enable_rtree=yes +fi + ######### # See whether we should enable RTREE # Check whether --enable-rtree was given. if test "${enable_rtree+set}" = set; then : - enableval=$enable_rtree; enable_rtree=yes -else - enable_rtree=no + enableval=$enable_rtree; fi if test "${enable_rtree}" = "yes" ; then @@ -11556,9 +11641,7 @@ fi # See whether we should enable the SESSION extension # Check whether --enable-session was given. if test "${enable_session+set}" = set; then : - enableval=$enable_session; enable_session=yes -else - enable_session=no + enableval=$enable_session; fi if test "${enable_session}" = "yes" ; then @@ -11621,9 +11704,7 @@ BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS # See whether we should use GCOV # Check whether --enable-gcov was given. if test "${enable_gcov+set}" = set; then : - enableval=$enable_gcov; use_gcov=$enableval -else - use_gcov=no + enableval=$enable_gcov; fi if test "${use_gcov}" = "yes" ; then @@ -12151,7 +12232,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.21.0, which was +This file was extended by sqlite $as_me 3.26.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12217,7 +12298,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.21.0 +sqlite config.status 3.26.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4deee8ddcb..9cf87adcad 100644 --- a/configure.ac +++ b/configure.ac @@ -120,7 +120,7 @@ USE_AMALGAMATION=1 # if not, then we fall back to plain tclsh. # TODO: try other versions before falling back? # -AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh8.5 tclsh], none) +AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.7 tclsh8.6 tclsh8.5 tclsh], none) if test "$TCLSH_CMD" = "none"; then # If we can't find a local tclsh, then building the amalgamation will fail. # We act as though --disable-amalgamation has been used. @@ -182,7 +182,7 @@ AC_SUBST(BUILD_CC) # Do we want to support multithreaded use of sqlite # AC_ARG_ENABLE(threadsafe, -AC_HELP_STRING([--disable-threadsafe],[Disable mutexing]),,enable_threadsafe=yes) +AC_HELP_STRING([--disable-threadsafe],[Disable mutexing])) AC_MSG_CHECKING([whether to support threadsafe operation]) if test "$enable_threadsafe" = "no"; then SQLITE_THREADSAFE=0 @@ -557,9 +557,8 @@ AC_SEARCH_LIBS(fdatasync, [rt]) ######### # check for debug enabled -AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]), - [use_debug=$enableval],[use_debug=no]) -if test "${use_debug}" = "yes" ; then +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain])) +if test "${enable_debug}" = "yes" ; then TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" else TARGET_DEBUG="-DNDEBUG" @@ -569,19 +568,23 @@ AC_SUBST(TARGET_DEBUG) ######### # See whether we should use the amalgamation to build AC_ARG_ENABLE(amalgamation, AC_HELP_STRING([--disable-amalgamation], - [Disable the amalgamation and instead build all files separately]), - [use_amalgamation=$enableval],[use_amalgamation=yes]) -if test "${use_amalgamation}" != "yes" ; then + [Disable the amalgamation and instead build all files separately])) +if test "${enable_amalgamation}" == "no" ; then USE_AMALGAMATION=0 fi AC_SUBST(USE_AMALGAMATION) +######### +# Look for zlib. Only needed by extensions and by the sqlite3.exe shell +AC_CHECK_HEADERS(zlib.h) +AC_SEARCH_LIBS(deflate, z, [HAVE_ZLIB="-DSQLITE_HAVE_ZLIB=1"], [HAVE_ZLIB=""]) +AC_SUBST(HAVE_ZLIB) + ######### # See whether we should allow loadable extensions AC_ARG_ENABLE(load-extension, AC_HELP_STRING([--disable-load-extension], - [Disable loading of external extensions]), - [use_loadextension=$enableval],[use_loadextension=yes]) -if test "${use_loadextension}" = "yes" ; then + [Disable loading of external extensions]),,[enable_load_extension=yes]) +if test "${enable_load_extension}" = "yes" ; then OPT_FEATURE_FLAGS="" AC_SEARCH_LIBS(dlopen, dl) else @@ -592,8 +595,7 @@ fi # Do we want to support memsys3 and/or memsys5 # AC_ARG_ENABLE(memsys5, - AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]), - [enable_memsys5=yes],[enable_memsys5=no]) + AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5])) AC_MSG_CHECKING([whether to support MEMSYS5]) if test "${enable_memsys5}" = "yes"; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" @@ -602,8 +604,7 @@ else AC_MSG_RESULT([no]) fi AC_ARG_ENABLE(memsys3, - AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]), - [enable_memsys3=yes],[enable_memsys3=no]) + AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3])) AC_MSG_CHECKING([whether to support MEMSYS3]) if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3" @@ -615,21 +616,18 @@ fi ######### # See whether we should enable Full Text Search extensions AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3], - [Enable the FTS3 extension]), - [enable_fts3=yes],[enable_fts3=no]) + [Enable the FTS3 extension])) if test "${enable_fts3}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" fi AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4], - [Enable the FTS4 extension]), - [enable_fts4=yes],[enable_fts4=no]) + [Enable the FTS4 extension])) if test "${enable_fts4}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" AC_SEARCH_LIBS([log],[m]) fi AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5], - [Enable the FTS5 extension]), - [enable_fts5=yes],[enable_fts5=no]) + [Enable the FTS5 extension])) if test "${enable_fts5}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" AC_SEARCH_LIBS([log],[m]) @@ -637,18 +635,34 @@ fi ######### # See whether we should enable JSON1 -AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1], - [Enable the JSON1 extension]), - [enable_json1=yes],[enable_json1=no]) +AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension])) if test "${enable_json1}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" fi +######### +# See whether we should enable the LIMIT clause on UPDATE and DELETE +# statements. +AC_ARG_ENABLE(update-limit, AC_HELP_STRING([--enable-update-limit], + [Enable the UPDATE/DELETE LIMIT clause])) +if test "${enable_udlimit}" = "yes" ; then + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" +fi + +######### +# See whether we should enable GEOPOLY +AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly], + [Enable the GEOPOLY extension]), + [enable_geopoly=yes],[enable_geopoly=no]) +if test "${enable_geopoly}" = "yes" ; then + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" + enable_rtree=yes +fi + ######### # See whether we should enable RTREE AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree], - [Enable the RTREE extension]), - [enable_rtree=yes],[enable_rtree=no]) + [Enable the RTREE extension])) if test "${enable_rtree}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" fi @@ -656,8 +670,7 @@ fi ######### # See whether we should enable the SESSION extension AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session], - [Enable the SESSION extension]), - [enable_session=yes],[enable_session=no]) + [Enable the SESSION extension])) if test "${enable_session}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" @@ -717,8 +730,7 @@ BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS ######### # See whether we should use GCOV AC_ARG_ENABLE(gcov, AC_HELP_STRING([--enable-gcov], - [Enable coverage testing using gcov]), - [use_gcov=$enableval],[use_gcov=no]) + [Enable coverage testing using gcov])) if test "${use_gcov}" = "yes" ; then USE_GCOV=1 else diff --git a/doc/F2FS.txt b/doc/F2FS.txt new file mode 100644 index 0000000000..47ad2297f4 --- /dev/null +++ b/doc/F2FS.txt @@ -0,0 +1,87 @@ + +SQLite's OS layer contains the following definitions used in F2FS related +calls: + +#define F2FS_IOCTL_MAGIC 0xf5 +#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) +#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) +#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3) +#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) +#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32) +#define F2FS_FEATURE_ATOMIC_WRITE 0x0004 + +After opening a database file on Linux (including Android), SQLite determines +whether or not a file supports F2FS atomic commits as follows: + + u32 flags = 0; + rc = ioctl(fd, F2FS_IOC_GET_FEATURES, &flags); + if( rc==0 && (flags & F2FS_FEATURE_ATOMIC_WRITE) ){ + /* File supports F2FS atomic commits */ + }else{ + /* File does NOT support F2FS atomic commits */ + } + +where "fd" is the file-descriptor open on the database file. + +Usually, when writing to a database file that supports atomic commits, SQLite +accumulates the entire transaction in heap memory, deferring all writes to the +db file until the transaction is committed. + +When it is time to commit a transaction on a file that supports atomic +commits, SQLite does: + + /* Take an F_WRLCK lock on the database file. This prevents any other + ** SQLite clients from reading or writing the file until the lock + ** is released. */ + rc = fcntl(fd, F_SETLK, ...); + if( rc!=0 ) goto failed; + + rc = ioctl(fd, F2FS_IOC_START_ATOMIC_WRITE); + if( rc!=0 ) goto fallback_to_legacy_journal_commit; + + foreach (dirty page){ + rc = write(fd, ...dirty page...); + if( rc!=0 ){ + ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE); + goto fallback_to_legacy_journal_commit; + } + } + + rc = ioctl(fd, F2FS_IOC_COMMIT_ATOMIC_WRITE); + if( rc!=0 ){ + ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE); + goto fallback_to_legacy_journal_commit; + } + + /* If we get there, the transaction has been successfully + ** committed to persistent storage. The following call + ** relinquishes the F_WRLCK lock. */ + fcntl(fd, F_SETLK, ...); + +Assumptions: + +1. After either of the F2FS_IOC_ABORT_VOLATILE_WRITE calls return, + the database file is in the state that it was in before + F2FS_IOC_START_ATOMIC_WRITE was invoked. Even if the ioctl() + fails - we're ignoring the return code. + + This is true regardless of the type of error that occurred in + ioctl() or write(). + +2. If the system fails before the F2FS_IOC_COMMIT_ATOMIC_WRITE is + completed, then following a reboot the database file is in the + state that it was in before F2FS_IOC_START_ATOMIC_WRITE was invoked. + Or, if the write was commited right before the system failed, in a + state indicating that all write() calls were successfully committed + to persistent storage before the failure occurred. + +3. If the process crashes before the F2FS_IOC_COMMIT_ATOMIC_WRITE is + completed then the file is automatically restored to the state that + it was in before F2FS_IOC_START_ATOMIC_WRITE was called. This occurs + before the posix advisory lock is automatically dropped - there is + no chance that another client will be able to read the file in a + half-committed state before the rollback operation occurs. + + + + diff --git a/doc/lemon.html b/doc/lemon.html index f05c481d79..4f0849e6d6 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -2,12 +2,12 @@ The Lemon Parser Generator - -

The Lemon Parser Generator

+ +

The Lemon Parser Generator

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

@@ -58,8 +58,8 @@ Lemon comes with a default parser template which works fine for most applications. But the user is free to substitute a different parser template if desired.

-

Depending on command-line options, Lemon will generate between -one and three files of outputs. +

Depending on command-line options, Lemon will generate up to +three output files.

  • C code to implement the parser.
  • A header file defining an integer ID for each terminal symbol. @@ -90,17 +90,23 @@ the states used by the parser automaton.

    You can obtain a list of the available command-line options together with a brief explanation of what each does by typing
    -   lemon -?
    +   lemon "-?"
     
    As of this writing, the following command-line options are supported:
    • -b Show only the basis for each parser state in the report file.
    • -c -Do not compress the generated action tables. +Do not compress the generated action tables. The parser will be a +little larger and slower, but it will detect syntax errors sooner. +
    • -ddirectory +Write all output files into directory. Normally, output files +are written into the directory that contains the input grammar file.
    • -Dname -Define C preprocessor macro name. This macro is useable by -"%ifdef" lines in the grammar file. +Define C preprocessor macro name. This macro is usable by +"%ifdef" and +"%ifndef" lines +in the grammar file.
    • -g Do not generate a parser. Instead write the input grammar to standard output with all comments, actions, and other extraneous text removed. @@ -108,9 +114,9 @@ output with all comments, actions, and other extraneous text removed. Omit "#line" directives in the generated parser C code.
    • -m Cause the output C source code to be compatible with the "makeheaders" -program. +program.
    • -p -Display all conflicts that are resolved by +Display all conflicts that are resolved by precedence rules.
    • -q Suppress generation of the report file. @@ -165,7 +171,7 @@ once for each token: The first argument to the Parse() routine is the pointer returned by ParseAlloc(). -The second argument is a small positive integer that tells the parse the +The second argument is a small positive integer that tells the parser the type of the next token in the data stream. There is one token type for each terminal symbol in the grammar. The gram.h file generated by Lemon contains #define statements that @@ -173,7 +179,7 @@ map symbolic terminal symbol names into appropriate integer values. A value of 0 for the second argument is a special flag to the parser to indicate that the end of input has been reached. The third argument is the value of the given token. By default, -the type of the third argument is integer, but the grammar will +the type of the third argument is "void*", but the grammar will usually redefine this type to be some kind of structure. Typically the second argument will be a broad category of tokens such as "identifier" or "number" and the third argument will @@ -181,7 +187,7 @@ be the name of the identifier or the value of the number.

      The Parse() function may have either three or four arguments, depending on the grammar. If the grammar specification file requests -it (via the extra_argument directive), +it (via the %extra_argument directive), the Parse() function will have a fourth parameter that can be of any type chosen by the programmer. The parser doesn't do anything with this argument except to pass it through to action routines. @@ -191,20 +197,20 @@ to the action routines without having to use global variables.

      A typical use of a Lemon parser might look something like the following:

      -   01 ParseTree *ParseFile(const char *zFilename){
      -   02    Tokenizer *pTokenizer;
      -   03    void *pParser;
      -   04    Token sToken;
      -   05    int hTokenId;
      -   06    ParserState sState;
      -   07
      -   08    pTokenizer = TokenizerCreate(zFilename);
      -   09    pParser = ParseAlloc( malloc );
      -   10    InitParserState(&sState);
      -   11    while( GetNextToken(pTokenizer, &hTokenId, &sToken) ){
      -   12       Parse(pParser, hTokenId, sToken, &sState);
      +    1 ParseTree *ParseFile(const char *zFilename){
      +    2    Tokenizer *pTokenizer;
      +    3    void *pParser;
      +    4    Token sToken;
      +    5    int hTokenId;
      +    6    ParserState sState;
      +    7
      +    8    pTokenizer = TokenizerCreate(zFilename);
      +    9    pParser = ParseAlloc( malloc );
      +   10    InitParserState(&sState);
      +   11    while( GetNextToken(pTokenizer, &hTokenId, &sToken) ){
      +   12       Parse(pParser, hTokenId, sToken, &sState);
          13    }
      -   14    Parse(pParser, 0, sToken, &sState);
      +   14    Parse(pParser, 0, sToken, &sState);
          15    ParseFree(pParser, free );
          16    TokenizerFree(pTokenizer);
          17    return sState.treeRoot;
      @@ -217,10 +223,10 @@ simple.)
       We assume the existence of some kind of tokenizer which is created
       using TokenizerCreate() on line 8 and deleted by TokenizerFree()
       on line 16.  The GetNextToken() function on line 11 retrieves the
      -next token from the input file and puts its type in the 
      +next token from the input file and puts its type in the
       integer variable hTokenId.  The sToken variable is assumed to be
       some kind of structure that contains details about each token,
      -such as its complete text, what line it occurs on, etc. 

      +such as its complete text, what line it occurs on, etc.

      This example also assumes the existence of structure of type ParserState that holds state information about a particular parse. @@ -237,7 +243,7 @@ tree.

          ParseFile(){
             pParser = ParseAlloc( malloc );
      -      while( GetNextToken(pTokenizer,&hTokenId, &sToken) ){
      +      while( GetNextToken(pTokenizer,&hTokenId, &sToken) ){
                Parse(pParser, hTokenId, sToken);
             }
             Parse(pParser, 0, sToken);
      @@ -297,25 +303,25 @@ specifies additional information Lemon requires to do its job.
       Most of the work in using Lemon is in writing an appropriate
       grammar file.

      -

      The grammar file for lemon is, for the most part, free format. +

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

      +tokens), and it honors the same commenting conventions as C and C++.

      Terminals and Nonterminals

      A terminal symbol (token) is any string of alphanumeric and/or underscore characters -that begins with an upper case letter. +that begins with an uppercase letter. A terminal can contain lowercase letters after the first character, -but the usual convention is to make terminals all upper case. +but the usual convention is to make terminals all uppercase. A nonterminal, on the other hand, is any string of alphanumeric -and underscore characters than begins with a lower case letter. -Again, the usual convention is to make nonterminals use all lower -case letters.

      +and underscore characters than begins with a lowercase letter. +Again, the usual convention is to make nonterminals use all lowercase +letters.

      -

      In Lemon, terminal and nonterminal symbols do not need to +

      In Lemon, terminal and nonterminal symbols do not need to be declared or identified in a separate section of the grammar file. Lemon is able to generate a list of all terminals and nonterminals by examining the grammar rules, and it can always distinguish a @@ -339,7 +345,8 @@ The list of terminals and nonterminals on the right-hand side of the rule can be empty. Rules can occur in any order, except that the left-hand side of the first rule is assumed to be the start symbol for the grammar (unless -specified otherwise using the %start directive described below.) +specified otherwise using the %start_symbol +directive described below.) A typical sequence of grammar rules might look something like this:

         expr ::= expr PLUS expr.
      @@ -382,7 +389,7 @@ names to each symbol in a grammar rule and then using those symbolic
       names in the action.
       In yacc or bison, one would write this:
       
      -  expr -> expr PLUS expr  { $$ = $1 + $3; };
      +  expr -> expr PLUS expr  { $$ = $1 + $3; };
       
      But in Lemon, the same rule becomes the following:
      @@ -422,14 +429,14 @@ of the shift, and a reduce-reduce conflict is resolved by reducing
       whichever rule comes first in the grammar file.

      Just like in -yacc and bison, Lemon allows a measure of control -over the resolution of paring conflicts using precedence rules. +yacc and bison, Lemon allows a measure of control +over the resolution of parsing conflicts using precedence rules. A precedence value can be assigned to any terminal symbol -using the -%left, -%right or -%nonassoc directives. Terminal symbols -mentioned in earlier directives have a lower precedence that +using the +%left, +%right or +%nonassoc directives. Terminal symbols +mentioned in earlier directives have a lower precedence than terminal symbols mentioned in later directives. For example:

      @@ -505,29 +512,29 @@ as follows:
       
    • If the precedence of the token to be shifted is greater than the precedence of the rule to reduce, then resolve in favor of the shift. No parsing conflict is reported. -
    • If the precedence of the token it be shifted is less than the +
    • If the precedence of the token to be shifted is less than the precedence of the rule to reduce, then resolve in favor of the reduce action. No parsing conflict is reported.
    • If the precedences are the same and the shift token is right-associative, then resolve in favor of the shift. No parsing conflict is reported. -
    • If the precedences are the same the shift token is +
    • If the precedences are the same and the shift token is left-associative, then resolve in favor of the reduce. No parsing conflict is reported. -
    • Otherwise, resolve the conflict by doing the shift and - report the parsing conflict. +
    • Otherwise, resolve the conflict by doing the shift, and + report a parsing conflict.
    Reduce-reduce conflicts are resolved this way:
      -
    • If either reduce rule +
    • If either reduce rule lacks precedence information, then resolve in favor of the - rule that appears first in the grammar and report a parsing + rule that appears first in the grammar, and report a parsing conflict. -
    • If both rules have precedence and the precedence is different +
    • If both rules have precedence and the precedence is different, then resolve the dispute in favor of the rule with the highest - precedence and do not report a conflict. + precedence, and do not report a conflict.
    • Otherwise, resolve the conflict by reducing by the rule that - appears first in the grammar and report a parsing conflict. + appears first in the grammar, and report a parsing conflict.

    Special Directives

    @@ -536,40 +543,40 @@ Reduce-reduce conflicts are resolved this way: directives. We've described all the grammar rules, so now we'll talk about the special directives.

    -

    Directives in lemon can occur in any order. You can put them before -the grammar rules, or after the grammar rules, or in the mist of the +

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

    Lemon supports the following special directives:

    Each of these directives will be described separately in the following sections:

    @@ -577,43 +584,42 @@ following sections:

    The %code directive

    -

    The %code directive is used to specify addition C code that +

    The %code directive is used to specify additional C code that is added to the end of the main output file. This is similar to -the %include directive except that %include -is inserted at the beginning of the main output file.

    +the %include directive except that +%include is inserted at the beginning of the main output file.

    -

    %code is typically used to include some action routines or perhaps -a tokenizer or even the "main()" function +

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

    The %default_destructor directive

    -

    The %default_destructor directive specifies a destructor to +

    The %default_destructor directive specifies a destructor to use for non-terminals that do not have their own destructor -specified by a separate %destructor directive. See the documentation -on the %destructor directive below for +specified by a separate %destructor directive. See the documentation +on the %destructor directive below for additional information.

    -

    In some grammers, many different non-terminal symbols have the -same datatype and hence the same destructor. This directive is -a convenience way to specify the same destructor for all those +

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

    The %default_type directive

    -

    The %default_type directive specifies the datatype of non-terminal -symbols that do no have their own datatype defined using a separate -%type directive. -

    +

    The %default_type directive specifies the data type of non-terminal +symbols that do not have their own data type defined using a separate +%type directive.

    The %destructor directive

    -

    The %destructor directive is used to specify a destructor for +

    The %destructor directive is used to specify a destructor for a non-terminal symbol. -(See also the %token_destructor +(See also the %token_destructor directive which is used to specify a destructor for terminal symbols.)

    A non-terminal's destructor is called to dispose of the @@ -635,7 +641,7 @@ or other resources held by that non-terminal.

    %destructor nt { free($$); } nt(A) ::= ID NUM. { A = malloc( 100 ); } -This example is a bit contrived but it serves to illustrate how +This example is a bit contrived, but it serves to illustrate how destructors work. The example shows a non-terminal named "nt" that holds values of type "void*". When the rule for an "nt" reduces, it sets the value of the non-terminal to @@ -651,17 +657,17 @@ stack, unless the non-terminal is used in a C-code action. If the non-terminal is used by C-code, then it is assumed that the C-code will take care of destroying it. More commonly, the value is used to build some -larger structure and we don't want to destroy it, which is why +larger structure, and we don't want to destroy it, which is why the destructor is not called in this circumstance.

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

    - +

    The %extra_argument directive

    -The %extra_argument directive instructs Lemon to add a 4th parameter +The %extra_argument directive instructs Lemon to add a 4th parameter to the parameter list of the Parse() function it generates. Lemon doesn't do anything itself with this extra argument, but it does make the argument available to C-code action routines, destructors, @@ -676,64 +682,91 @@ of type "MyStruct*" and all action routines will have access to a variable named "pAbc" that is the value of the 4th parameter in the most recent call to Parse().

    +

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

    The %extra_context directive

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

    + +

    +    %extra_context { MyStruct *pAbc }
    +

    + +

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

    + +

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

    The %fallback directive

    -

    The %fallback directive specifies an alternative meaning for one +

    The %fallback directive specifies an alternative meaning for one or more tokens. The alternative meaning is tried if the original token -would have generated a syntax error. +would have generated a syntax error.

    -

    The %fallback directive was added to support robust parsing of SQL -syntax in SQLite. +

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

    -

    The syntax of %fallback is as follows: +

    The syntax of %fallback is as follows:

    -%fallback ID TOKEN... . -
    +%fallback ID TOKEN... . +

    -

    In words, the %fallback directive is followed by a list of token names -terminated by a period. The first token name is the fallback token - the +

    In words, the %fallback directive is followed by a list of token +names terminated by a period. +The first token name is the fallback token — the token to which all the other tokens fall back to. The second and subsequent arguments are tokens which fall back to the token identified by the first -argument. +argument.

    -

    The %ifdef, %ifndef, and %endif directives.

    +

    The %ifdef, %ifndef, and %endif directives

    -

    The %ifdef, %ifndef, and %endif directives are similar to -#ifdef, #ifndef, and #endif in the C-preprocessor, just not as general. +

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

    -

    Grammar text in between "%ifdef MACRO" and the next nested "%endif" is +

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

    -

    Note that the argument to %ifdef and %ifndef must be a single -preprocessor symbol name, not a general expression. There is no "%else" -directive. +

    Note that the argument to %ifdef and %ifndef must +be a single preprocessor symbol name, not a general expression. +There is no "%else" directive.

    The %include directive

    -

    The %include directive specifies C code that is included at the -top of the generated parser. You can include any text you want -- +

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

    +%include directives in your grammar file, their values are concatenated +so that all %include code ultimately appears near the top of the +generated parser, in the same order as it appeared in the grammar.

    -

    The %include directive is very handy for getting some extra #include +

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

    @@ -742,17 +775,19 @@ For example:

    This might be needed, for example, if some of the C actions in the -grammar call functions that are prototyed in unistd.h.

    +grammar call functions that are prototyped in unistd.h.

    The %left directive

    -The %left directive is used (along with the %right and -%nonassoc directives) to declare precedences of -terminal symbols. Every terminal symbol whose name appears after -a %left directive but before the next period (".") is +The %left directive is used (along with the +%right and +%nonassoc directives) to declare +precedences of terminal symbols. +Every terminal symbol whose name appears after +a %left directive but before the next period (".") is given the same left-associative precedence value. Subsequent -%left directives have higher precedence. For example:

    +%left directives have higher precedence. For example:

        %left AND.
    @@ -763,20 +798,21 @@ given the same left-associative precedence value.  Subsequent
        %right EXP NOT.
     

    -

    Note the period that terminates each %left, %right or %nonassoc +

    Note the period that terminates each %left, +%right or %nonassoc directive.

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

    +operators. For this reason, it is recommended that you use %left +rather than %right whenever possible.

    The %name directive

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

    +different using the %name directive. For instance:

        %name Abcde
    @@ -790,22 +826,22 @@ functions named
     
  • AbcdeTrace(), and
  • Abcde().
-The %name directive allows you to generator two or more different -parsers and link them all into the same executable. -

+The %name directive allows you to generate two or more different +parsers and link them all into the same executable.

The %nonassoc directive

This directive is used to assign non-associative precedence to -one or more terminal symbols. See the section on +one or more terminal symbols. See the section on precedence rules -or on the %left directive for additional information.

+or on the %left directive +for additional information.

The %parse_accept directive

-

The %parse_accept directive specifies a block of C code that is +

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

@@ -821,7 +857,7 @@ without error.

The %parse_failure directive

-

The %parse_failure directive specifies a block of C code that +

The %parse_failure directive specifies a block of C code that is executed whenever the parser fails complete. This code is not executed until the parser has tried and failed to resolve an input error using is usual error recovery strategy. The routine is @@ -837,14 +873,14 @@ only invoked when parsing is unable to continue.

The %right directive

This directive is used to assign right-associative precedence to -one or more terminal symbols. See the section on +one or more terminal symbols. See the section on precedence rules or on the %left directive for additional information.

The %stack_overflow directive

-

The %stack_overflow directive specifies a block of C code that +

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

@@ -857,7 +893,7 @@ will be unable to continue and must be reset.

You can help prevent parser stack overflows by avoiding the use of right recursion and right-precedence operators in your grammar. -Use left recursion and and left-precedence operators instead, to +Use left recursion and and left-precedence operators instead to encourage rules to reduce sooner and keep the stack size down. For example, do rules like this:

@@ -868,7 +904,7 @@ Not like this:
 
    list ::= element list.      // right-recursion.  Bad!
    list ::= .
-
+

The %stack_size directive

@@ -876,7 +912,7 @@ Not like this:

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

@@ -886,25 +922,40 @@ with a stack of the requested size.  The default value is 100.

The %start_symbol directive

-

By default, the start-symbol for the grammar that Lemon generates +

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

+can choose a different start symbol using the +%start_symbol directive.

    %start_symbol  prog
 

+ +

The %syntax_error directive

+ +

See Error Processing.

+ + +

The %token_class directive

+ +

Undocumented. Appears to be related to the MULTITERMINAL concept. +Implementation.

+

The %token_destructor directive

-

The %destructor directive assigns a destructor to a non-terminal -symbol. (See the description of the %destructor directive above.) -This directive does the same thing for all terminal symbols.

+

The %destructor directive assigns a destructor to a non-terminal +symbol. (See the description of the +%destructor directive above.) +The %token_destructor directive does the same thing +for all terminal symbols.

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

@@ -913,8 +964,9 @@ destructors.

Lemon generates #defines that assign small integer constants to each terminal symbol in the grammar. If desired, Lemon will add a prefix specified by this directive -to each of the #defines it generates. -So if the default output of Lemon looked like this: +to each of the #defines it generates.

+ +

So if the default output of Lemon looked like this:

     #define AND              1
     #define MINUS            2
@@ -931,7 +983,7 @@ to cause Lemon to produce these symbols instead:
     #define TOKEN_MINUS      2
     #define TOKEN_OR         3
     #define TOKEN_PLUS       4
-
+

The %token_type and %type directives

@@ -952,7 +1004,7 @@ token structure. Like this:

is "void*".

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

@@ -973,14 +1025,15 @@ and able to pay that price, fine. You just need to know.

The %wildcard directive

-

The %wildcard directive is followed by a single token name and a -period. This directive specifies that the identified token should -match any input token. +

The %wildcard directive is followed by a single token name and a +period. This directive specifies that the identified token should +match any input token.

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

+

Error Processing

After extensive experimentation over several years, it has been @@ -988,19 +1041,20 @@ discovered that the error recovery strategy used by yacc is about as good as it gets. And so that is what Lemon uses.

When a Lemon-generated parser encounters a syntax error, it -first invokes the code specified by the %syntax_error directive, if +first invokes the code specified by the %syntax_error directive, if any. It then enters its error recovery strategy. The error recovery strategy is to begin popping the parsers stack until it enters a state where it is permitted to shift a special non-terminal symbol named "error". It then shifts this non-terminal and continues -parsing. But the %syntax_error routine will not be called again +parsing. The %syntax_error routine will not be called again until at least three new tokens have been successfully shifted.

If the parser pops its stack until the stack is empty, and it still -is unable to shift the error symbol, then the %parse_failed routine +is unable to shift the error symbol, then the +%parse_failure routine is invoked and the parser resets itself to its start state, ready to begin parsing a new file. This is what will happen at the very -first syntax error, of course, if there are no instances of the +first syntax error, of course, if there are no instances of the "error" non-terminal in your grammar.

diff --git a/ext/expert/README.md b/ext/expert/README.md new file mode 100644 index 0000000000..28886fd1f2 --- /dev/null +++ b/ext/expert/README.md @@ -0,0 +1,83 @@ +## SQLite Expert Extension + +This folder contains code for a simple system to propose useful indexes +given a database and a set of SQL queries. It works as follows: + + 1. The user database schema is copied to a temporary database. + + 1. All SQL queries are prepared against the temporary database. + Information regarding the WHERE and ORDER BY clauses, and other query + features that affect index selection are recorded. + + 1. The information gathered in step 2 is used to create candidate + indexes - indexes that the planner might have made use of in the previous + step, had they been available. + + 1. A subset of the data in the user database is used to generate statistics + for all existing indexes and the candidate indexes generated in step 3 + above. + + 1. The SQL queries are prepared a second time. If the planner uses any + of the indexes created in step 3, they are recommended to the user. + +# C API + +The SQLite expert C API is defined in sqlite3expert.h. Most uses will proceed +as follows: + + 1. An sqlite3expert object is created by calling **sqlite3\_expert\_new()**. + A database handle opened by the user is passed as an argument. + + 1. The sqlite3expert object is configured with one or more SQL statements + by making one or more calls to **sqlite3\_expert\_sql()**. Each call may + specify a single SQL statement, or multiple statements separated by + semi-colons. + + 1. Optionally, the **sqlite3\_expert\_config()** API may be used to + configure the size of the data subset used to generate index statistics. + Using a smaller subset of the data can speed up the analysis. + + 1. **sqlite3\_expert\_analyze()** is called to run the analysis. + + 1. One or more calls are made to **sqlite3\_expert\_report()** to extract + components of the results of the analysis. + + 1. **sqlite3\_expert\_destroy()** is called to free all resources. + +Refer to comments in sqlite3expert.h for further details. + +# sqlite3_expert application + +The file "expert.c" contains the code for a command line application that +uses the API described above. It can be compiled with (for example): + +
+  gcc -O2 sqlite3.c expert.c sqlite3expert.c -o sqlite3_expert
+
+ +Assuming the database is named "test.db", it can then be run to analyze a +single query: + +
+  ./sqlite3_expert -sql <sql-query> test.db
+
+ +Or an entire text file worth of queries with: + +
+  ./sqlite3_expert -file <text-file> test.db
+
+ +By default, sqlite3\_expert generates index statistics using all the data in +the user database. For a large database, this may be prohibitively time +consuming. The "-sample" option may be used to configure sqlite3\_expert to +generate statistics based on an integer percentage of the user database as +follows: + +
+  # Generate statistics based on 25% of the user database rows:
+  ./sqlite3_expert -sample 25 -sql <sql-query> test.db
+
+  # Do not generate any statistics at all:
+  ./sqlite3_expert -sample 0 -sql <sql-query> test.db
+
diff --git a/ext/expert/expert.c b/ext/expert/expert.c new file mode 100644 index 0000000000..051480f896 --- /dev/null +++ b/ext/expert/expert.c @@ -0,0 +1,156 @@ +/* +** 2017 April 07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + + +#include +#include +#include +#include +#include "sqlite3expert.h" + + +static void option_requires_argument(const char *zOpt){ + fprintf(stderr, "Option requires an argument: %s\n", zOpt); + exit(-3); +} + +static int option_integer_arg(const char *zVal){ + return atoi(zVal); +} + +static void usage(char **argv){ + fprintf(stderr, "\n"); + fprintf(stderr, "Usage %s ?OPTIONS? DATABASE\n", argv[0]); + fprintf(stderr, "\n"); + fprintf(stderr, "Options are:\n"); + fprintf(stderr, " -sql SQL (analyze SQL statements passed as argument)\n"); + fprintf(stderr, " -file FILE (read SQL statements from file FILE)\n"); + fprintf(stderr, " -verbose LEVEL (integer verbosity level. default 1)\n"); + fprintf(stderr, " -sample PERCENT (percent of db to sample. default 100)\n"); + exit(-1); +} + +static int readSqlFromFile(sqlite3expert *p, const char *zFile, char **pzErr){ + FILE *in = fopen(zFile, "rb"); + long nIn; + size_t nRead; + char *pBuf; + int rc; + if( in==0 ){ + *pzErr = sqlite3_mprintf("failed to open file %s\n", zFile); + return SQLITE_ERROR; + } + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc64( nIn+1 ); + nRead = fread(pBuf, nIn, 1, in); + fclose(in); + if( nRead!=1 ){ + sqlite3_free(pBuf); + *pzErr = sqlite3_mprintf("failed to read file %s\n", zFile); + return SQLITE_ERROR; + } + pBuf[nIn] = 0; + rc = sqlite3_expert_sql(p, pBuf, pzErr); + sqlite3_free(pBuf); + return rc; +} + +int main(int argc, char **argv){ + const char *zDb; + int rc = 0; + char *zErr = 0; + int i; + int iVerbose = 1; /* -verbose option */ + + sqlite3 *db = 0; + sqlite3expert *p = 0; + + if( argc<2 ) usage(argv); + zDb = argv[argc-1]; + if( zDb[0]=='-' ) usage(argv); + rc = sqlite3_open(zDb, &db); + if( rc!=SQLITE_OK ){ + fprintf(stderr, "Cannot open db file: %s - %s\n", zDb, sqlite3_errmsg(db)); + exit(-2); + } + + p = sqlite3_expert_new(db, &zErr); + if( p==0 ){ + fprintf(stderr, "Cannot run analysis: %s\n", zErr); + rc = 1; + }else{ + for(i=1; i<(argc-1); i++){ + char *zArg = argv[i]; + int nArg; + if( zArg[0]=='-' && zArg[1]=='-' && zArg[2]!=0 ) zArg++; + nArg = (int)strlen(zArg); + if( nArg>=2 && 0==sqlite3_strnicmp(zArg, "-file", nArg) ){ + if( ++i==(argc-1) ) option_requires_argument("-file"); + rc = readSqlFromFile(p, argv[i], &zErr); + } + + else if( nArg>=3 && 0==sqlite3_strnicmp(zArg, "-sql", nArg) ){ + if( ++i==(argc-1) ) option_requires_argument("-sql"); + rc = sqlite3_expert_sql(p, argv[i], &zErr); + } + + else if( nArg>=3 && 0==sqlite3_strnicmp(zArg, "-sample", nArg) ){ + int iSample; + if( ++i==(argc-1) ) option_requires_argument("-sample"); + iSample = option_integer_arg(argv[i]); + sqlite3_expert_config(p, EXPERT_CONFIG_SAMPLE, iSample); + } + + else if( nArg>=2 && 0==sqlite3_strnicmp(zArg, "-verbose", nArg) ){ + if( ++i==(argc-1) ) option_requires_argument("-verbose"); + iVerbose = option_integer_arg(argv[i]); + } + + else{ + usage(argv); + } + } + } + + if( rc==SQLITE_OK ){ + rc = sqlite3_expert_analyze(p, &zErr); + } + + if( rc==SQLITE_OK ){ + int nQuery = sqlite3_expert_count(p); + if( iVerbose>0 ){ + const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES); + fprintf(stdout, "-- Candidates -------------------------------\n"); + fprintf(stdout, "%s\n", zCand); + } + for(i=0; i0 ){ + fprintf(stdout, "-- Query %d ----------------------------------\n",i+1); + fprintf(stdout, "%s\n\n", zSql); + } + fprintf(stdout, "%s\n%s\n", zIdx, zEQP); + } + }else{ + fprintf(stderr, "Error: %s\n", zErr ? zErr : "?"); + } + + sqlite3_expert_destroy(p); + sqlite3_free(zErr); + return rc; +} diff --git a/ext/expert/expert1.test b/ext/expert/expert1.test new file mode 100644 index 0000000000..2b4668340d --- /dev/null +++ b/ext/expert/expert1.test @@ -0,0 +1,382 @@ +# 2009 Nov 11 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the CLI shell tool. Specifically, +# the ".recommend" command. +# +# + +# Test plan: +# +# +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set testprefix expert1 + +if {[info commands sqlite3_expert_new]==""} { + finish_test + return +} + +set CLI [test_binary_name sqlite3] +set CMD [test_binary_name sqlite3_expert] + +proc squish {txt} { + regsub -all {[[:space:]]+} $txt { } +} + +proc do_setup_rec_test {tn setup sql res} { + reset_db + db eval $setup + uplevel [list do_rec_test $tn $sql $res] +} + +foreach {tn setup} { + 1 { + if {![file executable $CMD]} { continue } + + proc do_rec_test {tn sql res} { + set res [squish [string trim $res]] + set tst [subst -nocommands { + squish [string trim [exec $::CMD -verbose 0 -sql {$sql;} test.db]] + }] + uplevel [list do_test $tn $tst $res] + } + } + 2 { + if {[info commands sqlite3_expert_new]==""} { continue } + + proc do_rec_test {tn sql res} { + set expert [sqlite3_expert_new db] + $expert sql $sql + $expert analyze + + set result [list] + for {set i 0} {$i < [$expert count]} {incr i} { + set idx [string trim [$expert report $i indexes]] + if {$idx==""} {set idx "(no new indexes)"} + lappend result $idx + lappend result [string trim [$expert report $i plan]] + } + + $expert destroy + + set tst [subst -nocommands {set {} [squish [join {$result}]]}] + uplevel [list do_test $tn $tst [string trim [squish $res]]] + } + } + 3 { + if {![file executable $CLI]} { continue } + + proc do_rec_test {tn sql res} { + set res [squish [string trim $res]] + set tst [subst -nocommands { + squish [string trim [exec $::CLI test.db ".expert" {$sql;}]] + }] + uplevel [list do_test $tn $tst $res] + } + } +} { + + eval $setup + + +do_setup_rec_test $tn.1 { CREATE TABLE t1(a, b, c) } { + SELECT * FROM t1 +} { + (no new indexes) + SCAN TABLE t1 +} + +do_setup_rec_test $tn.2 { + CREATE TABLE t1(a, b, c); +} { + SELECT * FROM t1 WHERE b>?; +} { + CREATE INDEX t1_idx_00000062 ON t1(b); + SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?) +} + +do_setup_rec_test $tn.3 { + CREATE TABLE t1(a, b, c); +} { + SELECT * FROM t1 WHERE b COLLATE nocase BETWEEN ? AND ? +} { + CREATE INDEX t1_idx_3e094c27 ON t1(b COLLATE NOCASE); + SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b? AND b +#include +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; + +typedef struct IdxColumn IdxColumn; +typedef struct IdxConstraint IdxConstraint; +typedef struct IdxScan IdxScan; +typedef struct IdxStatement IdxStatement; +typedef struct IdxTable IdxTable; +typedef struct IdxWrite IdxWrite; + +#define STRLEN (int)strlen + +/* +** A temp table name that we assume no user database will actually use. +** If this assumption proves incorrect triggers on the table with the +** conflicting name will be ignored. +*/ +#define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776" + +/* +** A single constraint. Equivalent to either "col = ?" or "col < ?" (or +** any other type of single-ended range constraint on a column). +** +** pLink: +** Used to temporarily link IdxConstraint objects into lists while +** creating candidate indexes. +*/ +struct IdxConstraint { + char *zColl; /* Collation sequence */ + int bRange; /* True for range, false for eq */ + int iCol; /* Constrained table column */ + int bFlag; /* Used by idxFindCompatible() */ + int bDesc; /* True if ORDER BY DESC */ + IdxConstraint *pNext; /* Next constraint in pEq or pRange list */ + IdxConstraint *pLink; /* See above */ +}; + +/* +** A single scan of a single table. +*/ +struct IdxScan { + IdxTable *pTab; /* Associated table object */ + int iDb; /* Database containing table zTable */ + i64 covering; /* Mask of columns required for cov. index */ + IdxConstraint *pOrder; /* ORDER BY columns */ + IdxConstraint *pEq; /* List of == constraints */ + IdxConstraint *pRange; /* List of < constraints */ + IdxScan *pNextScan; /* Next IdxScan object for same analysis */ +}; + +/* +** Information regarding a single database table. Extracted from +** "PRAGMA table_info" by function idxGetTableInfo(). +*/ +struct IdxColumn { + char *zName; + char *zColl; + int iPk; +}; +struct IdxTable { + int nCol; + char *zName; /* Table name */ + IdxColumn *aCol; + IdxTable *pNext; /* Next table in linked list of all tables */ +}; + +/* +** An object of the following type is created for each unique table/write-op +** seen. The objects are stored in a singly-linked list beginning at +** sqlite3expert.pWrite. +*/ +struct IdxWrite { + IdxTable *pTab; + int eOp; /* SQLITE_UPDATE, DELETE or INSERT */ + IdxWrite *pNext; +}; + +/* +** Each statement being analyzed is represented by an instance of this +** structure. +*/ +struct IdxStatement { + int iId; /* Statement number */ + char *zSql; /* SQL statement */ + char *zIdx; /* Indexes */ + char *zEQP; /* Plan */ + IdxStatement *pNext; +}; + + +/* +** A hash table for storing strings. With space for a payload string +** with each entry. Methods are: +** +** idxHashInit() +** idxHashClear() +** idxHashAdd() +** idxHashSearch() +*/ +#define IDX_HASH_SIZE 1023 +typedef struct IdxHashEntry IdxHashEntry; +typedef struct IdxHash IdxHash; +struct IdxHashEntry { + char *zKey; /* nul-terminated key */ + char *zVal; /* nul-terminated value string */ + char *zVal2; /* nul-terminated value string 2 */ + IdxHashEntry *pHashNext; /* Next entry in same hash bucket */ + IdxHashEntry *pNext; /* Next entry in hash */ +}; +struct IdxHash { + IdxHashEntry *pFirst; + IdxHashEntry *aHash[IDX_HASH_SIZE]; +}; + +/* +** sqlite3expert object. +*/ +struct sqlite3expert { + int iSample; /* Percentage of tables to sample for stat1 */ + sqlite3 *db; /* User database */ + sqlite3 *dbm; /* In-memory db for this analysis */ + sqlite3 *dbv; /* Vtab schema for this analysis */ + IdxTable *pTable; /* List of all IdxTable objects */ + IdxScan *pScan; /* List of scan objects */ + IdxWrite *pWrite; /* List of write objects */ + IdxStatement *pStatement; /* List of IdxStatement objects */ + int bRun; /* True once analysis has run */ + char **pzErrmsg; + int rc; /* Error code from whereinfo hook */ + IdxHash hIdx; /* Hash containing all candidate indexes */ + char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */ +}; + + +/* +** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). +** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL. +*/ +static void *idxMalloc(int *pRc, int nByte){ + void *pRet; + assert( *pRc==SQLITE_OK ); + assert( nByte>0 ); + pRet = sqlite3_malloc(nByte); + if( pRet ){ + memset(pRet, 0, nByte); + }else{ + *pRc = SQLITE_NOMEM; + } + return pRet; +} + +/* +** Initialize an IdxHash hash table. +*/ +static void idxHashInit(IdxHash *pHash){ + memset(pHash, 0, sizeof(IdxHash)); +} + +/* +** Reset an IdxHash hash table. +*/ +static void idxHashClear(IdxHash *pHash){ + int i; + for(i=0; iaHash[i]; pEntry; pEntry=pNext){ + pNext = pEntry->pHashNext; + sqlite3_free(pEntry->zVal2); + sqlite3_free(pEntry); + } + } + memset(pHash, 0, sizeof(IdxHash)); +} + +/* +** Return the index of the hash bucket that the string specified by the +** arguments to this function belongs. +*/ +static int idxHashString(const char *z, int n){ + unsigned int ret = 0; + int i; + for(i=0; i=0 ); + for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ + if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ + return 1; + } + } + pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1); + if( pEntry ){ + pEntry->zKey = (char*)&pEntry[1]; + memcpy(pEntry->zKey, zKey, nKey); + if( zVal ){ + pEntry->zVal = &pEntry->zKey[nKey+1]; + memcpy(pEntry->zVal, zVal, nVal); + } + pEntry->pHashNext = pHash->aHash[iHash]; + pHash->aHash[iHash] = pEntry; + + pEntry->pNext = pHash->pFirst; + pHash->pFirst = pEntry; + } + return 0; +} + +/* +** If zKey/nKey is present in the hash table, return a pointer to the +** hash-entry object. +*/ +static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){ + int iHash; + IdxHashEntry *pEntry; + if( nKey<0 ) nKey = STRLEN(zKey); + iHash = idxHashString(zKey, nKey); + assert( iHash>=0 ); + for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ + if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ + return pEntry; + } + } + return 0; +} + +/* +** If the hash table contains an entry with a key equal to the string +** passed as the final two arguments to this function, return a pointer +** to the payload string. Otherwise, if zKey/nKey is not present in the +** hash table, return NULL. +*/ +static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){ + IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey); + if( pEntry ) return pEntry->zVal; + return 0; +} + +/* +** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl +** variable to point to a copy of nul-terminated string zColl. +*/ +static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){ + IdxConstraint *pNew; + int nColl = STRLEN(zColl); + + assert( *pRc==SQLITE_OK ); + pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1); + if( pNew ){ + pNew->zColl = (char*)&pNew[1]; + memcpy(pNew->zColl, zColl, nColl+1); + } + return pNew; +} + +/* +** An error associated with database handle db has just occurred. Pass +** the error message to callback function xOut. +*/ +static void idxDatabaseError( + sqlite3 *db, /* Database handle */ + char **pzErrmsg /* Write error here */ +){ + *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); +} + +/* +** Prepare an SQL statement. +*/ +static int idxPrepareStmt( + sqlite3 *db, /* Database handle to compile against */ + sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ + char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ + const char *zSql /* SQL statement to compile */ +){ + int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); + if( rc!=SQLITE_OK ){ + *ppStmt = 0; + idxDatabaseError(db, pzErrmsg); + } + return rc; +} + +/* +** Prepare an SQL statement using the results of a printf() formatting. +*/ +static int idxPrintfPrepareStmt( + sqlite3 *db, /* Database handle to compile against */ + sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ + char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ + const char *zFmt, /* printf() format of SQL statement */ + ... /* Trailing printf() arguments */ +){ + va_list ap; + int rc; + char *zSql; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql); + sqlite3_free(zSql); + } + va_end(ap); + return rc; +} + + +/************************************************************************* +** Beginning of virtual table implementation. +*/ +typedef struct ExpertVtab ExpertVtab; +struct ExpertVtab { + sqlite3_vtab base; + IdxTable *pTab; + sqlite3expert *pExpert; +}; + +typedef struct ExpertCsr ExpertCsr; +struct ExpertCsr { + sqlite3_vtab_cursor base; + sqlite3_stmt *pData; +}; + +static char *expertDequote(const char *zIn){ + int n = STRLEN(zIn); + char *zRet = sqlite3_malloc(n); + + assert( zIn[0]=='\'' ); + assert( zIn[n-1]=='\'' ); + + if( zRet ){ + int iOut = 0; + int iIn = 0; + for(iIn=1; iIn<(n-1); iIn++){ + if( zIn[iIn]=='\'' ){ + assert( zIn[iIn+1]=='\'' ); + iIn++; + } + zRet[iOut++] = zIn[iIn]; + } + zRet[iOut] = '\0'; + } + + return zRet; +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the r-tree virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int expertConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3expert *pExpert = (sqlite3expert*)pAux; + ExpertVtab *p = 0; + int rc; + + if( argc!=4 ){ + *pzErr = sqlite3_mprintf("internal error!"); + rc = SQLITE_ERROR; + }else{ + char *zCreateTable = expertDequote(argv[3]); + if( zCreateTable ){ + rc = sqlite3_declare_vtab(db, zCreateTable); + if( rc==SQLITE_OK ){ + p = idxMalloc(&rc, sizeof(ExpertVtab)); + } + if( rc==SQLITE_OK ){ + p->pExpert = pExpert; + p->pTab = pExpert->pTable; + assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 ); + } + sqlite3_free(zCreateTable); + }else{ + rc = SQLITE_NOMEM; + } + } + + *ppVtab = (sqlite3_vtab*)p; + return rc; +} + +static int expertDisconnect(sqlite3_vtab *pVtab){ + ExpertVtab *p = (ExpertVtab*)pVtab; + sqlite3_free(p); + return SQLITE_OK; +} + +static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ + ExpertVtab *p = (ExpertVtab*)pVtab; + int rc = SQLITE_OK; + int n = 0; + IdxScan *pScan; + const int opmask = + SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | + SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE | + SQLITE_INDEX_CONSTRAINT_LE; + + pScan = idxMalloc(&rc, sizeof(IdxScan)); + if( pScan ){ + int i; + + /* Link the new scan object into the list */ + pScan->pTab = p->pTab; + pScan->pNextScan = p->pExpert->pScan; + p->pExpert->pScan = pScan; + + /* Add the constraints to the IdxScan object */ + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; + if( pCons->usable + && pCons->iColumn>=0 + && p->pTab->aCol[pCons->iColumn].iPk==0 + && (pCons->op & opmask) + ){ + IdxConstraint *pNew; + const char *zColl = sqlite3_vtab_collation(pIdxInfo, i); + pNew = idxNewConstraint(&rc, zColl); + if( pNew ){ + pNew->iCol = pCons->iColumn; + if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + pNew->pNext = pScan->pEq; + pScan->pEq = pNew; + }else{ + pNew->bRange = 1; + pNew->pNext = pScan->pRange; + pScan->pRange = pNew; + } + } + n++; + pIdxInfo->aConstraintUsage[i].argvIndex = n; + } + } + + /* Add the ORDER BY to the IdxScan object */ + for(i=pIdxInfo->nOrderBy-1; i>=0; i--){ + int iCol = pIdxInfo->aOrderBy[i].iColumn; + if( iCol>=0 ){ + IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); + if( pNew ){ + pNew->iCol = iCol; + pNew->bDesc = pIdxInfo->aOrderBy[i].desc; + pNew->pNext = pScan->pOrder; + pNew->pLink = pScan->pOrder; + pScan->pOrder = pNew; + n++; + } + } + } + } + + pIdxInfo->estimatedCost = 1000000.0 / (n+1); + return rc; +} + +static int expertUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **azData, + sqlite_int64 *pRowid +){ + (void)pVtab; + (void)nData; + (void)azData; + (void)pRowid; + return SQLITE_OK; +} + +/* +** Virtual table module xOpen method. +*/ +static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + int rc = SQLITE_OK; + ExpertCsr *pCsr; + (void)pVTab; + pCsr = idxMalloc(&rc, sizeof(ExpertCsr)); + *ppCursor = (sqlite3_vtab_cursor*)pCsr; + return rc; +} + +/* +** Virtual table module xClose method. +*/ +static int expertClose(sqlite3_vtab_cursor *cur){ + ExpertCsr *pCsr = (ExpertCsr*)cur; + sqlite3_finalize(pCsr->pData); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Virtual table module xEof method. +** +** Return non-zero if the cursor does not currently point to a valid +** record (i.e if the scan has finished), or zero otherwise. +*/ +static int expertEof(sqlite3_vtab_cursor *cur){ + ExpertCsr *pCsr = (ExpertCsr*)cur; + return pCsr->pData==0; +} + +/* +** Virtual table module xNext method. +*/ +static int expertNext(sqlite3_vtab_cursor *cur){ + ExpertCsr *pCsr = (ExpertCsr*)cur; + int rc = SQLITE_OK; + + assert( pCsr->pData ); + rc = sqlite3_step(pCsr->pData); + if( rc!=SQLITE_ROW ){ + rc = sqlite3_finalize(pCsr->pData); + pCsr->pData = 0; + }else{ + rc = SQLITE_OK; + } + + return rc; +} + +/* +** Virtual table module xRowid method. +*/ +static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + (void)cur; + *pRowid = 0; + return SQLITE_OK; +} + +/* +** Virtual table module xColumn method. +*/ +static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + ExpertCsr *pCsr = (ExpertCsr*)cur; + sqlite3_value *pVal; + pVal = sqlite3_column_value(pCsr->pData, i); + if( pVal ){ + sqlite3_result_value(ctx, pVal); + } + return SQLITE_OK; +} + +/* +** Virtual table module xFilter method. +*/ +static int expertFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + ExpertCsr *pCsr = (ExpertCsr*)cur; + ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab); + sqlite3expert *pExpert = pVtab->pExpert; + int rc; + + (void)idxNum; + (void)idxStr; + (void)argc; + (void)argv; + rc = sqlite3_finalize(pCsr->pData); + pCsr->pData = 0; + if( rc==SQLITE_OK ){ + rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, + "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName + ); + } + + if( rc==SQLITE_OK ){ + rc = expertNext(cur); + } + return rc; +} + +static int idxRegisterVtab(sqlite3expert *p){ + static sqlite3_module expertModule = { + 2, /* iVersion */ + expertConnect, /* xCreate - create a table */ + expertConnect, /* xConnect - connect to an existing table */ + expertBestIndex, /* xBestIndex - Determine search strategy */ + expertDisconnect, /* xDisconnect - Disconnect from a table */ + expertDisconnect, /* xDestroy - Drop a table */ + expertOpen, /* xOpen - open a cursor */ + expertClose, /* xClose - close a cursor */ + expertFilter, /* xFilter - configure scan constraints */ + expertNext, /* xNext - advance a cursor */ + expertEof, /* xEof */ + expertColumn, /* xColumn - read data */ + expertRowid, /* xRowid - read data */ + expertUpdate, /* xUpdate - write data */ + 0, /* xBegin - begin transaction */ + 0, /* xSync - sync transaction */ + 0, /* xCommit - commit transaction */ + 0, /* xRollback - rollback transaction */ + 0, /* xFindFunction - function overloading */ + 0, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + }; + + return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p); +} +/* +** End of virtual table implementation. +*************************************************************************/ +/* +** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function +** is called, set it to the return value of sqlite3_finalize() before +** returning. Otherwise, discard the sqlite3_finalize() return value. +*/ +static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){ + int rc = sqlite3_finalize(pStmt); + if( *pRc==SQLITE_OK ) *pRc = rc; +} + +/* +** Attempt to allocate an IdxTable structure corresponding to table zTab +** in the main database of connection db. If successful, set (*ppOut) to +** point to the new object and return SQLITE_OK. Otherwise, return an +** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be +** set to point to an error string. +** +** It is the responsibility of the caller to eventually free either the +** IdxTable object or error message using sqlite3_free(). +*/ +static int idxGetTableInfo( + sqlite3 *db, /* Database connection to read details from */ + const char *zTab, /* Table name */ + IdxTable **ppOut, /* OUT: New object (if successful) */ + char **pzErrmsg /* OUT: Error message (if not) */ +){ + sqlite3_stmt *p1 = 0; + int nCol = 0; + int nTab = STRLEN(zTab); + int nByte = sizeof(IdxTable) + nTab + 1; + IdxTable *pNew = 0; + int rc, rc2; + char *pCsr = 0; + + rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ + const char *zCol = (const char*)sqlite3_column_text(p1, 1); + nByte += 1 + STRLEN(zCol); + rc = sqlite3_table_column_metadata( + db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 + ); + nByte += 1 + STRLEN(zCol); + nCol++; + } + rc2 = sqlite3_reset(p1); + if( rc==SQLITE_OK ) rc = rc2; + + nByte += sizeof(IdxColumn) * nCol; + if( rc==SQLITE_OK ){ + pNew = idxMalloc(&rc, nByte); + } + if( rc==SQLITE_OK ){ + pNew->aCol = (IdxColumn*)&pNew[1]; + pNew->nCol = nCol; + pCsr = (char*)&pNew->aCol[nCol]; + } + + nCol = 0; + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ + const char *zCol = (const char*)sqlite3_column_text(p1, 1); + int nCopy = STRLEN(zCol) + 1; + pNew->aCol[nCol].zName = pCsr; + pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5); + memcpy(pCsr, zCol, nCopy); + pCsr += nCopy; + + rc = sqlite3_table_column_metadata( + db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 + ); + if( rc==SQLITE_OK ){ + nCopy = STRLEN(zCol) + 1; + pNew->aCol[nCol].zColl = pCsr; + memcpy(pCsr, zCol, nCopy); + pCsr += nCopy; + } + + nCol++; + } + idxFinalize(&rc, p1); + + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew); + pNew = 0; + }else{ + pNew->zName = pCsr; + memcpy(pNew->zName, zTab, nTab+1); + } + + *ppOut = pNew; + return rc; +} + +/* +** This function is a no-op if *pRc is set to anything other than +** SQLITE_OK when it is called. +** +** If *pRc is initially set to SQLITE_OK, then the text specified by +** the printf() style arguments is appended to zIn and the result returned +** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on +** zIn before returning. +*/ +static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){ + va_list ap; + char *zAppend = 0; + char *zRet = 0; + int nIn = zIn ? STRLEN(zIn) : 0; + int nAppend = 0; + va_start(ap, zFmt); + if( *pRc==SQLITE_OK ){ + zAppend = sqlite3_vmprintf(zFmt, ap); + if( zAppend ){ + nAppend = STRLEN(zAppend); + zRet = (char*)sqlite3_malloc(nIn + nAppend + 1); + } + if( zAppend && zRet ){ + if( nIn ) memcpy(zRet, zIn, nIn); + memcpy(&zRet[nIn], zAppend, nAppend+1); + }else{ + sqlite3_free(zRet); + zRet = 0; + *pRc = SQLITE_NOMEM; + } + sqlite3_free(zAppend); + sqlite3_free(zIn); + } + va_end(ap); + return zRet; +} + +/* +** Return true if zId must be quoted in order to use it as an SQL +** identifier, or false otherwise. +*/ +static int idxIdentifierRequiresQuotes(const char *zId){ + int i; + for(i=0; zId[i]; i++){ + if( !(zId[i]=='_') + && !(zId[i]>='0' && zId[i]<='9') + && !(zId[i]>='a' && zId[i]<='z') + && !(zId[i]>='A' && zId[i]<='Z') + ){ + return 1; + } + } + return 0; +} + +/* +** This function appends an index column definition suitable for constraint +** pCons to the string passed as zIn and returns the result. +*/ +static char *idxAppendColDefn( + int *pRc, /* IN/OUT: Error code */ + char *zIn, /* Column defn accumulated so far */ + IdxTable *pTab, /* Table index will be created on */ + IdxConstraint *pCons +){ + char *zRet = zIn; + IdxColumn *p = &pTab->aCol[pCons->iCol]; + if( zRet ) zRet = idxAppendText(pRc, zRet, ", "); + + if( idxIdentifierRequiresQuotes(p->zName) ){ + zRet = idxAppendText(pRc, zRet, "%Q", p->zName); + }else{ + zRet = idxAppendText(pRc, zRet, "%s", p->zName); + } + + if( sqlite3_stricmp(p->zColl, pCons->zColl) ){ + if( idxIdentifierRequiresQuotes(pCons->zColl) ){ + zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl); + }else{ + zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl); + } + } + + if( pCons->bDesc ){ + zRet = idxAppendText(pRc, zRet, " DESC"); + } + return zRet; +} + +/* +** Search database dbm for an index compatible with the one idxCreateFromCons() +** would create from arguments pScan, pEq and pTail. If no error occurs and +** such an index is found, return non-zero. Or, if no such index is found, +** return zero. +** +** If an error occurs, set *pRc to an SQLite error code and return zero. +*/ +static int idxFindCompatible( + int *pRc, /* OUT: Error code */ + sqlite3* dbm, /* Database to search */ + IdxScan *pScan, /* Scan for table to search for index on */ + IdxConstraint *pEq, /* List of == constraints */ + IdxConstraint *pTail /* List of range constraints */ +){ + const char *zTbl = pScan->pTab->zName; + sqlite3_stmt *pIdxList = 0; + IdxConstraint *pIter; + int nEq = 0; /* Number of elements in pEq */ + int rc; + + /* Count the elements in list pEq */ + for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++; + + rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl); + while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){ + int bMatch = 1; + IdxConstraint *pT = pTail; + sqlite3_stmt *pInfo = 0; + const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1); + + /* Zero the IdxConstraint.bFlag values in the pEq list */ + for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0; + + rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx); + while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){ + int iIdx = sqlite3_column_int(pInfo, 0); + int iCol = sqlite3_column_int(pInfo, 1); + const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); + + if( iIdxpLink){ + if( pIter->bFlag ) continue; + if( pIter->iCol!=iCol ) continue; + if( sqlite3_stricmp(pIter->zColl, zColl) ) continue; + pIter->bFlag = 1; + break; + } + if( pIter==0 ){ + bMatch = 0; + break; + } + }else{ + if( pT ){ + if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){ + bMatch = 0; + break; + } + pT = pT->pLink; + } + } + } + idxFinalize(&rc, pInfo); + + if( rc==SQLITE_OK && bMatch ){ + sqlite3_finalize(pIdxList); + return 1; + } + } + idxFinalize(&rc, pIdxList); + + *pRc = rc; + return 0; +} + +static int idxCreateFromCons( + sqlite3expert *p, + IdxScan *pScan, + IdxConstraint *pEq, + IdxConstraint *pTail +){ + sqlite3 *dbm = p->dbm; + int rc = SQLITE_OK; + if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){ + IdxTable *pTab = pScan->pTab; + char *zCols = 0; + char *zIdx = 0; + IdxConstraint *pCons; + unsigned int h = 0; + const char *zFmt; + + for(pCons=pEq; pCons; pCons=pCons->pLink){ + zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); + } + for(pCons=pTail; pCons; pCons=pCons->pLink){ + zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); + } + + if( rc==SQLITE_OK ){ + /* Hash the list of columns to come up with a name for the index */ + const char *zTable = pScan->pTab->zName; + char *zName; /* Index name */ + int i; + for(i=0; zCols[i]; i++){ + h += ((h<<3) + zCols[i]); + } + zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); + if( zName==0 ){ + rc = SQLITE_NOMEM; + }else{ + if( idxIdentifierRequiresQuotes(zTable) ){ + zFmt = "CREATE INDEX '%q' ON %Q(%s)"; + }else{ + zFmt = "CREATE INDEX %s ON %s(%s)"; + } + zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols); + if( !zIdx ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg); + idxHashAdd(&rc, &p->hIdx, zName, zIdx); + } + sqlite3_free(zName); + sqlite3_free(zIdx); + } + } + + sqlite3_free(zCols); + } + return rc; +} + +/* +** Return true if list pList (linked by IdxConstraint.pLink) contains +** a constraint compatible with *p. Otherwise return false. +*/ +static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){ + IdxConstraint *pCmp; + for(pCmp=pList; pCmp; pCmp=pCmp->pLink){ + if( p->iCol==pCmp->iCol ) return 1; + } + return 0; +} + +static int idxCreateFromWhere( + sqlite3expert *p, + IdxScan *pScan, /* Create indexes for this scan */ + IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */ +){ + IdxConstraint *p1 = 0; + IdxConstraint *pCon; + int rc; + + /* Gather up all the == constraints. */ + for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){ + if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ + pCon->pLink = p1; + p1 = pCon; + } + } + + /* Create an index using the == constraints collected above. And the + ** range constraint/ORDER BY terms passed in by the caller, if any. */ + rc = idxCreateFromCons(p, pScan, p1, pTail); + + /* If no range/ORDER BY passed by the caller, create a version of the + ** index for each range constraint. */ + if( pTail==0 ){ + for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){ + assert( pCon->pLink==0 ); + if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ + rc = idxCreateFromCons(p, pScan, p1, pCon); + } + } + } + + return rc; +} + +/* +** Create candidate indexes in database [dbm] based on the data in +** linked-list pScan. +*/ +static int idxCreateCandidates(sqlite3expert *p){ + int rc = SQLITE_OK; + IdxScan *pIter; + + for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){ + rc = idxCreateFromWhere(p, pIter, 0); + if( rc==SQLITE_OK && pIter->pOrder ){ + rc = idxCreateFromWhere(p, pIter, pIter->pOrder); + } + } + + return rc; +} + +/* +** Free all elements of the linked list starting at pConstraint. +*/ +static void idxConstraintFree(IdxConstraint *pConstraint){ + IdxConstraint *pNext; + IdxConstraint *p; + + for(p=pConstraint; p; p=pNext){ + pNext = p->pNext; + sqlite3_free(p); + } +} + +/* +** Free all elements of the linked list starting from pScan up until pLast +** (pLast is not freed). +*/ +static void idxScanFree(IdxScan *pScan, IdxScan *pLast){ + IdxScan *p; + IdxScan *pNext; + for(p=pScan; p!=pLast; p=pNext){ + pNext = p->pNextScan; + idxConstraintFree(p->pOrder); + idxConstraintFree(p->pEq); + idxConstraintFree(p->pRange); + sqlite3_free(p); + } +} + +/* +** Free all elements of the linked list starting from pStatement up +** until pLast (pLast is not freed). +*/ +static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){ + IdxStatement *p; + IdxStatement *pNext; + for(p=pStatement; p!=pLast; p=pNext){ + pNext = p->pNext; + sqlite3_free(p->zEQP); + sqlite3_free(p->zIdx); + sqlite3_free(p); + } +} + +/* +** Free the linked list of IdxTable objects starting at pTab. +*/ +static void idxTableFree(IdxTable *pTab){ + IdxTable *pIter; + IdxTable *pNext; + for(pIter=pTab; pIter; pIter=pNext){ + pNext = pIter->pNext; + sqlite3_free(pIter); + } +} + +/* +** Free the linked list of IdxWrite objects starting at pTab. +*/ +static void idxWriteFree(IdxWrite *pTab){ + IdxWrite *pIter; + IdxWrite *pNext; + for(pIter=pTab; pIter; pIter=pNext){ + pNext = pIter->pNext; + sqlite3_free(pIter); + } +} + + + +/* +** This function is called after candidate indexes have been created. It +** runs all the queries to see which indexes they prefer, and populates +** IdxStatement.zIdx and IdxStatement.zEQP with the results. +*/ +int idxFindIndexes( + sqlite3expert *p, + char **pzErr /* OUT: Error message (sqlite3_malloc) */ +){ + IdxStatement *pStmt; + sqlite3 *dbm = p->dbm; + int rc = SQLITE_OK; + + IdxHash hIdx; + idxHashInit(&hIdx); + + for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){ + IdxHashEntry *pEntry; + sqlite3_stmt *pExplain = 0; + idxHashClear(&hIdx); + rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, + "EXPLAIN QUERY PLAN %s", pStmt->zSql + ); + while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ + /* int iId = sqlite3_column_int(pExplain, 0); */ + /* int iParent = sqlite3_column_int(pExplain, 1); */ + /* int iNotUsed = sqlite3_column_int(pExplain, 2); */ + const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); + int nDetail = STRLEN(zDetail); + int i; + + for(i=0; ihIdx, zIdx, nIdx); + if( zSql ){ + idxHashAdd(&rc, &hIdx, zSql, 0); + if( rc ) goto find_indexes_out; + } + break; + } + } + + if( zDetail[0]!='-' ){ + pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail); + } + } + + for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ + pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey); + } + + idxFinalize(&rc, pExplain); + } + + find_indexes_out: + idxHashClear(&hIdx); + return rc; +} + +static int idxAuthCallback( + void *pCtx, + int eOp, + const char *z3, + const char *z4, + const char *zDb, + const char *zTrigger +){ + int rc = SQLITE_OK; + (void)z4; + (void)zTrigger; + if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){ + if( sqlite3_stricmp(zDb, "main")==0 ){ + sqlite3expert *p = (sqlite3expert*)pCtx; + IdxTable *pTab; + for(pTab=p->pTable; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_stricmp(z3, pTab->zName) ) break; + } + if( pTab ){ + IdxWrite *pWrite; + for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){ + if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break; + } + if( pWrite==0 ){ + pWrite = idxMalloc(&rc, sizeof(IdxWrite)); + if( rc==SQLITE_OK ){ + pWrite->pTab = pTab; + pWrite->eOp = eOp; + pWrite->pNext = p->pWrite; + p->pWrite = pWrite; + } + } + } + } + } + return rc; +} + +static int idxProcessOneTrigger( + sqlite3expert *p, + IdxWrite *pWrite, + char **pzErr +){ + static const char *zInt = UNIQUE_TABLE_NAME; + static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME; + IdxTable *pTab = pWrite->pTab; + const char *zTab = pTab->zName; + const char *zSql = + "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master " + "WHERE tbl_name = %Q AND type IN ('table', 'trigger') " + "ORDER BY type;"; + sqlite3_stmt *pSelect = 0; + int rc = SQLITE_OK; + char *zWrite = 0; + + /* Create the table and its triggers in the temp schema */ + rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){ + const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0); + rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr); + } + idxFinalize(&rc, pSelect); + + /* Rename the table in the temp schema to zInt */ + if( rc==SQLITE_OK ){ + char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt); + if( z==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr); + sqlite3_free(z); + } + } + + switch( pWrite->eOp ){ + case SQLITE_INSERT: { + int i; + zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt); + for(i=0; inCol; i++){ + zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", "); + } + zWrite = idxAppendText(&rc, zWrite, ")"); + break; + } + case SQLITE_UPDATE: { + int i; + zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt); + for(i=0; inCol; i++){ + zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ", + pTab->aCol[i].zName + ); + } + break; + } + default: { + assert( pWrite->eOp==SQLITE_DELETE ); + if( rc==SQLITE_OK ){ + zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt); + if( zWrite==0 ) rc = SQLITE_NOMEM; + } + } + } + + if( rc==SQLITE_OK ){ + sqlite3_stmt *pX = 0; + rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0); + idxFinalize(&rc, pX); + if( rc!=SQLITE_OK ){ + idxDatabaseError(p->dbv, pzErr); + } + } + sqlite3_free(zWrite); + + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr); + } + + return rc; +} + +static int idxProcessTriggers(sqlite3expert *p, char **pzErr){ + int rc = SQLITE_OK; + IdxWrite *pEnd = 0; + IdxWrite *pFirst = p->pWrite; + + while( rc==SQLITE_OK && pFirst!=pEnd ){ + IdxWrite *pIter; + for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){ + rc = idxProcessOneTrigger(p, pIter, pzErr); + } + pEnd = pFirst; + pFirst = p->pWrite; + } + + return rc; +} + + +static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ + int rc = idxRegisterVtab(p); + sqlite3_stmt *pSchema = 0; + + /* For each table in the main db schema: + ** + ** 1) Add an entry to the p->pTable list, and + ** 2) Create the equivalent virtual table in dbv. + */ + rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg, + "SELECT type, name, sql, 1 FROM sqlite_master " + "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' " + " UNION ALL " + "SELECT type, name, sql, 2 FROM sqlite_master " + "WHERE type = 'trigger'" + " AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') " + "ORDER BY 4, 1" + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){ + const char *zType = (const char*)sqlite3_column_text(pSchema, 0); + const char *zName = (const char*)sqlite3_column_text(pSchema, 1); + const char *zSql = (const char*)sqlite3_column_text(pSchema, 2); + + if( zType[0]=='v' || zType[1]=='r' ){ + rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg); + }else{ + IdxTable *pTab; + rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); + if( rc==SQLITE_OK ){ + int i; + char *zInner = 0; + char *zOuter = 0; + pTab->pNext = p->pTable; + p->pTable = pTab; + + /* The statement the vtab will pass to sqlite3_declare_vtab() */ + zInner = idxAppendText(&rc, 0, "CREATE TABLE x("); + for(i=0; inCol; i++){ + zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s", + (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl + ); + } + zInner = idxAppendText(&rc, zInner, ")"); + + /* The CVT statement to create the vtab */ + zOuter = idxAppendText(&rc, 0, + "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg); + } + sqlite3_free(zInner); + sqlite3_free(zOuter); + } + } + } + idxFinalize(&rc, pSchema); + return rc; +} + +struct IdxSampleCtx { + int iTarget; + double target; /* Target nRet/nRow value */ + double nRow; /* Number of rows seen */ + double nRet; /* Number of rows returned */ +}; + +static void idxSampleFunc( + sqlite3_context *pCtx, + int argc, + sqlite3_value **argv +){ + struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx); + int bRet; + + (void)argv; + assert( argc==0 ); + if( p->nRow==0.0 ){ + bRet = 1; + }else{ + bRet = (p->nRet / p->nRow) <= p->target; + if( bRet==0 ){ + unsigned short rnd; + sqlite3_randomness(2, (void*)&rnd); + bRet = ((int)rnd % 100) <= p->iTarget; + } + } + + sqlite3_result_int(pCtx, bRet); + p->nRow += 1.0; + p->nRet += (double)bRet; +} + +struct IdxRemCtx { + int nSlot; + struct IdxRemSlot { + int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */ + i64 iVal; /* SQLITE_INTEGER value */ + double rVal; /* SQLITE_FLOAT value */ + int nByte; /* Bytes of space allocated at z */ + int n; /* Size of buffer z */ + char *z; /* SQLITE_TEXT/BLOB value */ + } aSlot[1]; +}; + +/* +** Implementation of scalar function rem(). +*/ +static void idxRemFunc( + sqlite3_context *pCtx, + int argc, + sqlite3_value **argv +){ + struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx); + struct IdxRemSlot *pSlot; + int iSlot; + assert( argc==2 ); + + iSlot = sqlite3_value_int(argv[0]); + assert( iSlot<=p->nSlot ); + pSlot = &p->aSlot[iSlot]; + + switch( pSlot->eType ){ + case SQLITE_NULL: + /* no-op */ + break; + + case SQLITE_INTEGER: + sqlite3_result_int64(pCtx, pSlot->iVal); + break; + + case SQLITE_FLOAT: + sqlite3_result_double(pCtx, pSlot->rVal); + break; + + case SQLITE_BLOB: + sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); + break; + + case SQLITE_TEXT: + sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); + break; + } + + pSlot->eType = sqlite3_value_type(argv[1]); + switch( pSlot->eType ){ + case SQLITE_NULL: + /* no-op */ + break; + + case SQLITE_INTEGER: + pSlot->iVal = sqlite3_value_int64(argv[1]); + break; + + case SQLITE_FLOAT: + pSlot->rVal = sqlite3_value_double(argv[1]); + break; + + case SQLITE_BLOB: + case SQLITE_TEXT: { + int nByte = sqlite3_value_bytes(argv[1]); + if( nByte>pSlot->nByte ){ + char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2); + if( zNew==0 ){ + sqlite3_result_error_nomem(pCtx); + return; + } + pSlot->nByte = nByte*2; + pSlot->z = zNew; + } + pSlot->n = nByte; + if( pSlot->eType==SQLITE_BLOB ){ + memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte); + }else{ + memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte); + } + break; + } + } +} + +static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){ + int rc = SQLITE_OK; + const char *zMax = + "SELECT max(i.seqno) FROM " + " sqlite_master AS s, " + " pragma_index_list(s.name) AS l, " + " pragma_index_info(l.name) AS i " + "WHERE s.type = 'table'"; + sqlite3_stmt *pMax = 0; + + *pnMax = 0; + rc = idxPrepareStmt(db, &pMax, pzErr, zMax); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + *pnMax = sqlite3_column_int(pMax, 0) + 1; + } + idxFinalize(&rc, pMax); + + return rc; +} + +static int idxPopulateOneStat1( + sqlite3expert *p, + sqlite3_stmt *pIndexXInfo, + sqlite3_stmt *pWriteStat, + const char *zTab, + const char *zIdx, + char **pzErr +){ + char *zCols = 0; + char *zOrder = 0; + char *zQuery = 0; + int nCol = 0; + int i; + sqlite3_stmt *pQuery = 0; + int *aStat = 0; + int rc = SQLITE_OK; + + assert( p->iSample>0 ); + + /* Formulate the query text */ + sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); + while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ + const char *zComma = zCols==0 ? "" : ", "; + const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); + const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); + zCols = idxAppendText(&rc, zCols, + "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl + ); + zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); + } + sqlite3_reset(pIndexXInfo); + if( rc==SQLITE_OK ){ + if( p->iSample==100 ){ + zQuery = sqlite3_mprintf( + "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder + ); + }else{ + zQuery = sqlite3_mprintf( + "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder + ); + } + } + sqlite3_free(zCols); + sqlite3_free(zOrder); + + /* Formulate the query text */ + if( rc==SQLITE_OK ){ + sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); + rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery); + } + sqlite3_free(zQuery); + + if( rc==SQLITE_OK ){ + aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1)); + } + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ + IdxHashEntry *pEntry; + char *zStat = 0; + for(i=0; i<=nCol; i++) aStat[i] = 1; + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ + aStat[0]++; + for(i=0; ihIdx, zIdx, STRLEN(zIdx)); + if( pEntry ){ + assert( pEntry->zVal2==0 ); + pEntry->zVal2 = zStat; + }else{ + sqlite3_free(zStat); + } + } + sqlite3_free(aStat); + idxFinalize(&rc, pQuery); + + return rc; +} + +static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){ + int rc; + char *zSql; + + rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); + if( rc!=SQLITE_OK ) return rc; + + zSql = sqlite3_mprintf( + "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab + ); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0); + sqlite3_free(zSql); + + return rc; +} + +/* +** This function is called as part of sqlite3_expert_analyze(). Candidate +** indexes have already been created in database sqlite3expert.dbm, this +** function populates sqlite_stat1 table in the same database. +** +** The stat1 data is generated by querying the +*/ +static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ + int rc = SQLITE_OK; + int nMax =0; + struct IdxRemCtx *pCtx = 0; + struct IdxSampleCtx samplectx; + int i; + i64 iPrev = -100000; + sqlite3_stmt *pAllIndex = 0; + sqlite3_stmt *pIndexXInfo = 0; + sqlite3_stmt *pWrite = 0; + + const char *zAllIndex = + "SELECT s.rowid, s.name, l.name FROM " + " sqlite_master AS s, " + " pragma_index_list(s.name) AS l " + "WHERE s.type = 'table'"; + const char *zIndexXInfo = + "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key"; + const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)"; + + /* If iSample==0, no sqlite_stat1 data is required. */ + if( p->iSample==0 ) return SQLITE_OK; + + rc = idxLargestIndex(p->dbm, &nMax, pzErr); + if( nMax<=0 || rc!=SQLITE_OK ) return rc; + + rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0); + + if( rc==SQLITE_OK ){ + int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); + pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte); + } + + if( rc==SQLITE_OK ){ + sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); + rc = sqlite3_create_function( + dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 + ); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 + ); + } + + if( rc==SQLITE_OK ){ + pCtx->nSlot = nMax+1; + rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex); + } + if( rc==SQLITE_OK ){ + rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo); + } + if( rc==SQLITE_OK ){ + rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite); + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){ + i64 iRowid = sqlite3_column_int64(pAllIndex, 0); + const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1); + const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2); + if( p->iSample<100 && iPrev!=iRowid ){ + samplectx.target = (double)p->iSample / 100.0; + samplectx.iTarget = p->iSample; + samplectx.nRow = 0.0; + samplectx.nRet = 0.0; + rc = idxBuildSampleTable(p, zTab); + if( rc!=SQLITE_OK ) break; + } + rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr); + iPrev = iRowid; + } + if( rc==SQLITE_OK && p->iSample<100 ){ + rc = sqlite3_exec(p->dbv, + "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0 + ); + } + + idxFinalize(&rc, pAllIndex); + idxFinalize(&rc, pIndexXInfo); + idxFinalize(&rc, pWrite); + + for(i=0; inSlot; i++){ + sqlite3_free(pCtx->aSlot[i].z); + } + sqlite3_free(pCtx); + + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0); + } + + sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); + return rc; +} + +/* +** Allocate a new sqlite3expert object. +*/ +sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ + int rc = SQLITE_OK; + sqlite3expert *pNew; + + pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert)); + + /* Open two in-memory databases to work with. The "vtab database" (dbv) + ** will contain a virtual table corresponding to each real table in + ** the user database schema, and a copy of each view. It is used to + ** collect information regarding the WHERE, ORDER BY and other clauses + ** of the user's query. + */ + if( rc==SQLITE_OK ){ + pNew->db = db; + pNew->iSample = 100; + rc = sqlite3_open(":memory:", &pNew->dbv); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_open(":memory:", &pNew->dbm); + if( rc==SQLITE_OK ){ + sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0); + } + } + + + /* Copy the entire schema of database [db] into [dbm]. */ + if( rc==SQLITE_OK ){ + sqlite3_stmt *pSql; + rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, + "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'" + " AND sql NOT LIKE 'CREATE VIRTUAL %%'" + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ + const char *zSql = (const char*)sqlite3_column_text(pSql, 0); + rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg); + } + idxFinalize(&rc, pSql); + } + + /* Create the vtab schema */ + if( rc==SQLITE_OK ){ + rc = idxCreateVtabSchema(pNew, pzErrmsg); + } + + /* Register the auth callback with dbv */ + if( rc==SQLITE_OK ){ + sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew); + } + + /* If an error has occurred, free the new object and reutrn NULL. Otherwise, + ** return the new sqlite3expert handle. */ + if( rc!=SQLITE_OK ){ + sqlite3_expert_destroy(pNew); + pNew = 0; + } + return pNew; +} + +/* +** Configure an sqlite3expert object. +*/ +int sqlite3_expert_config(sqlite3expert *p, int op, ...){ + int rc = SQLITE_OK; + va_list ap; + va_start(ap, op); + switch( op ){ + case EXPERT_CONFIG_SAMPLE: { + int iVal = va_arg(ap, int); + if( iVal<0 ) iVal = 0; + if( iVal>100 ) iVal = 100; + p->iSample = iVal; + break; + } + default: + rc = SQLITE_NOTFOUND; + break; + } + + va_end(ap); + return rc; +} + +/* +** Add an SQL statement to the analysis. +*/ +int sqlite3_expert_sql( + sqlite3expert *p, /* From sqlite3_expert_new() */ + const char *zSql, /* SQL statement to add */ + char **pzErr /* OUT: Error message (if any) */ +){ + IdxScan *pScanOrig = p->pScan; + IdxStatement *pStmtOrig = p->pStatement; + int rc = SQLITE_OK; + const char *zStmt = zSql; + + if( p->bRun ) return SQLITE_MISUSE; + + while( rc==SQLITE_OK && zStmt && zStmt[0] ){ + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); + if( rc==SQLITE_OK ){ + if( pStmt ){ + IdxStatement *pNew; + const char *z = sqlite3_sql(pStmt); + int n = STRLEN(z); + pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1); + if( rc==SQLITE_OK ){ + pNew->zSql = (char*)&pNew[1]; + memcpy(pNew->zSql, z, n+1); + pNew->pNext = p->pStatement; + if( p->pStatement ) pNew->iId = p->pStatement->iId+1; + p->pStatement = pNew; + } + sqlite3_finalize(pStmt); + } + }else{ + idxDatabaseError(p->dbv, pzErr); + } + } + + if( rc!=SQLITE_OK ){ + idxScanFree(p->pScan, pScanOrig); + idxStatementFree(p->pStatement, pStmtOrig); + p->pScan = pScanOrig; + p->pStatement = pStmtOrig; + } + + return rc; +} + +int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){ + int rc; + IdxHashEntry *pEntry; + + /* Do trigger processing to collect any extra IdxScan structures */ + rc = idxProcessTriggers(p, pzErr); + + /* Create candidate indexes within the in-memory database file */ + if( rc==SQLITE_OK ){ + rc = idxCreateCandidates(p); + } + + /* Generate the stat1 data */ + if( rc==SQLITE_OK ){ + rc = idxPopulateStat1(p, pzErr); + } + + /* Formulate the EXPERT_REPORT_CANDIDATES text */ + for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ + p->zCandidates = idxAppendText(&rc, p->zCandidates, + "%s;%s%s\n", pEntry->zVal, + pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2 + ); + } + + /* Figure out which of the candidate indexes are preferred by the query + ** planner and report the results to the user. */ + if( rc==SQLITE_OK ){ + rc = idxFindIndexes(p, pzErr); + } + + if( rc==SQLITE_OK ){ + p->bRun = 1; + } + return rc; +} + +/* +** Return the total number of statements that have been added to this +** sqlite3expert using sqlite3_expert_sql(). +*/ +int sqlite3_expert_count(sqlite3expert *p){ + int nRet = 0; + if( p->pStatement ) nRet = p->pStatement->iId+1; + return nRet; +} + +/* +** Return a component of the report. +*/ +const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){ + const char *zRet = 0; + IdxStatement *pStmt; + + if( p->bRun==0 ) return 0; + for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext); + switch( eReport ){ + case EXPERT_REPORT_SQL: + if( pStmt ) zRet = pStmt->zSql; + break; + case EXPERT_REPORT_INDEXES: + if( pStmt ) zRet = pStmt->zIdx; + break; + case EXPERT_REPORT_PLAN: + if( pStmt ) zRet = pStmt->zEQP; + break; + case EXPERT_REPORT_CANDIDATES: + zRet = p->zCandidates; + break; + } + return zRet; +} + +/* +** Free an sqlite3expert object. +*/ +void sqlite3_expert_destroy(sqlite3expert *p){ + if( p ){ + sqlite3_close(p->dbm); + sqlite3_close(p->dbv); + idxScanFree(p->pScan, 0); + idxStatementFree(p->pStatement, 0); + idxTableFree(p->pTable); + idxWriteFree(p->pWrite); + idxHashClear(&p->hIdx); + sqlite3_free(p->zCandidates); + sqlite3_free(p); + } +} + +#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */ diff --git a/ext/expert/sqlite3expert.h b/ext/expert/sqlite3expert.h new file mode 100644 index 0000000000..39135dc274 --- /dev/null +++ b/ext/expert/sqlite3expert.h @@ -0,0 +1,168 @@ +/* +** 2017 April 07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + + +#include "sqlite3.h" + +typedef struct sqlite3expert sqlite3expert; + +/* +** Create a new sqlite3expert object. +** +** If successful, a pointer to the new object is returned and (*pzErr) set +** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to +** an English-language error message. In this case it is the responsibility +** of the caller to eventually free the error message buffer using +** sqlite3_free(). +*/ +sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr); + +/* +** Configure an sqlite3expert object. +** +** EXPERT_CONFIG_SAMPLE: +** By default, sqlite3_expert_analyze() generates sqlite_stat1 data for +** each candidate index. This involves scanning and sorting the entire +** contents of each user database table once for each candidate index +** associated with the table. For large databases, this can be +** prohibitively slow. This option allows the sqlite3expert object to +** be configured so that sqlite_stat1 data is instead generated based on a +** subset of each table, or so that no sqlite_stat1 data is used at all. +** +** A single integer argument is passed to this option. If the value is less +** than or equal to zero, then no sqlite_stat1 data is generated or used by +** the analysis - indexes are recommended based on the database schema only. +** Or, if the value is 100 or greater, complete sqlite_stat1 data is +** generated for each candidate index (this is the default). Finally, if the +** value falls between 0 and 100, then it represents the percentage of user +** table rows that should be considered when generating sqlite_stat1 data. +** +** Examples: +** +** // Do not generate any sqlite_stat1 data +** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0); +** +** // Generate sqlite_stat1 data based on 10% of the rows in each table. +** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10); +*/ +int sqlite3_expert_config(sqlite3expert *p, int op, ...); + +#define EXPERT_CONFIG_SAMPLE 1 /* int */ + +/* +** Specify zero or more SQL statements to be included in the analysis. +** +** Buffer zSql must contain zero or more complete SQL statements. This +** function parses all statements contained in the buffer and adds them +** to the internal list of statements to analyze. If successful, SQLITE_OK +** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example +** due to a error in the SQL - an SQLite error code is returned and (*pzErr) +** may be set to point to an English language error message. In this case +** the caller is responsible for eventually freeing the error message buffer +** using sqlite3_free(). +** +** If an error does occur while processing one of the statements in the +** buffer passed as the second argument, none of the statements in the +** buffer are added to the analysis. +** +** This function must be called before sqlite3_expert_analyze(). If a call +** to this function is made on an sqlite3expert object that has already +** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned +** immediately and no statements are added to the analysis. +*/ +int sqlite3_expert_sql( + sqlite3expert *p, /* From a successful sqlite3_expert_new() */ + const char *zSql, /* SQL statement(s) to add */ + char **pzErr /* OUT: Error message (if any) */ +); + + +/* +** This function is called after the sqlite3expert object has been configured +** with all SQL statements using sqlite3_expert_sql() to actually perform +** the analysis. Once this function has been called, it is not possible to +** add further SQL statements to the analysis. +** +** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if +** an error occurs, an SQLite error code is returned and (*pzErr) set to +** point to a buffer containing an English language error message. In this +** case it is the responsibility of the caller to eventually free the buffer +** using sqlite3_free(). +** +** If an error does occur within this function, the sqlite3expert object +** is no longer useful for any purpose. At that point it is no longer +** possible to add further SQL statements to the object or to re-attempt +** the analysis. The sqlite3expert object must still be freed using a call +** sqlite3_expert_destroy(). +*/ +int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr); + +/* +** Return the total number of statements loaded using sqlite3_expert_sql(). +** The total number of SQL statements may be different from the total number +** to calls to sqlite3_expert_sql(). +*/ +int sqlite3_expert_count(sqlite3expert*); + +/* +** Return a component of the report. +** +** This function is called after sqlite3_expert_analyze() to extract the +** results of the analysis. Each call to this function returns either a +** NULL pointer or a pointer to a buffer containing a nul-terminated string. +** The value passed as the third argument must be one of the EXPERT_REPORT_* +** #define constants defined below. +** +** For some EXPERT_REPORT_* parameters, the buffer returned contains +** information relating to a specific SQL statement. In these cases that +** SQL statement is identified by the value passed as the second argument. +** SQL statements are numbered from 0 in the order in which they are parsed. +** If an out-of-range value (less than zero or equal to or greater than the +** value returned by sqlite3_expert_count()) is passed as the second argument +** along with such an EXPERT_REPORT_* parameter, NULL is always returned. +** +** EXPERT_REPORT_SQL: +** Return the text of SQL statement iStmt. +** +** EXPERT_REPORT_INDEXES: +** Return a buffer containing the CREATE INDEX statements for all recommended +** indexes for statement iStmt. If there are no new recommeded indexes, NULL +** is returned. +** +** EXPERT_REPORT_PLAN: +** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query +** iStmt after the proposed indexes have been added to the database schema. +** +** EXPERT_REPORT_CANDIDATES: +** Return a pointer to a buffer containing the CREATE INDEX statements +** for all indexes that were tested (for all SQL statements). The iStmt +** parameter is ignored for EXPERT_REPORT_CANDIDATES calls. +*/ +const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport); + +/* +** Values for the third argument passed to sqlite3_expert_report(). +*/ +#define EXPERT_REPORT_SQL 1 +#define EXPERT_REPORT_INDEXES 2 +#define EXPERT_REPORT_PLAN 3 +#define EXPERT_REPORT_CANDIDATES 4 + +/* +** Free an (sqlite3expert*) handle and all associated resources. There +** should be one call to this function for each successful call to +** sqlite3-expert_new(). +*/ +void sqlite3_expert_destroy(sqlite3expert*); + + diff --git a/ext/expert/test_expert.c b/ext/expert/test_expert.c new file mode 100644 index 0000000000..064c1908a9 --- /dev/null +++ b/ext/expert/test_expert.c @@ -0,0 +1,220 @@ +/* +** 2017 April 07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#if defined(SQLITE_TEST) + +#include "sqlite3expert.h" +#include +#include + +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* +** Extract an sqlite3* db handle from the object passed as the second +** argument. If successful, set *pDb to point to the db handle and return +** TCL_OK. Otherwise, return TCL_ERROR. +*/ +static int dbHandleFromObj(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){ + Tcl_CmdInfo info; + if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){ + Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), 0); + return TCL_ERROR; + } + + *pDb = *(sqlite3 **)info.objClientData; + return TCL_OK; +} + + +/* +** Tclcmd: $expert sql SQL +** $expert analyze +** $expert count +** $expert report STMT EREPORT +** $expert destroy +*/ +static int SQLITE_TCLAPI testExpertCmd( + void *clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3expert *pExpert = (sqlite3expert*)clientData; + struct Subcmd { + const char *zSub; + int nArg; + const char *zMsg; + } aSub[] = { + { "sql", 1, "TABLE", }, /* 0 */ + { "analyze", 0, "", }, /* 1 */ + { "count", 0, "", }, /* 2 */ + { "report", 2, "STMT EREPORT", }, /* 3 */ + { "destroy", 0, "", }, /* 4 */ + { 0 } + }; + int iSub; + int rc = TCL_OK; + char *zErr = 0; + + if( objc<2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); + return TCL_ERROR; + } + rc = Tcl_GetIndexFromObjStruct(interp, + objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub + ); + if( rc!=TCL_OK ) return rc; + if( objc!=2+aSub[iSub].nArg ){ + Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg); + return TCL_ERROR; + } + + switch( iSub ){ + case 0: { /* sql */ + char *zArg = Tcl_GetString(objv[2]); + rc = sqlite3_expert_sql(pExpert, zArg, &zErr); + break; + } + + case 1: { /* analyze */ + rc = sqlite3_expert_analyze(pExpert, &zErr); + break; + } + + case 2: { /* count */ + int n = sqlite3_expert_count(pExpert); + Tcl_SetObjResult(interp, Tcl_NewIntObj(n)); + break; + } + + case 3: { /* report */ + const char *aEnum[] = { + "sql", "indexes", "plan", "candidates", 0 + }; + int iEnum; + int iStmt; + const char *zReport; + + if( Tcl_GetIntFromObj(interp, objv[2], &iStmt) + || Tcl_GetIndexFromObj(interp, objv[3], aEnum, "report", 0, &iEnum) + ){ + return TCL_ERROR; + } + + assert( EXPERT_REPORT_SQL==1 ); + assert( EXPERT_REPORT_INDEXES==2 ); + assert( EXPERT_REPORT_PLAN==3 ); + assert( EXPERT_REPORT_CANDIDATES==4 ); + zReport = sqlite3_expert_report(pExpert, iStmt, 1+iEnum); + Tcl_SetObjResult(interp, Tcl_NewStringObj(zReport, -1)); + break; + } + + default: /* destroy */ + assert( iSub==4 ); + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); + break; + } + + if( rc!=TCL_OK ){ + if( zErr ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); + }else{ + extern const char *sqlite3ErrName(int); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + } + } + sqlite3_free(zErr); + return rc; +} + +static void SQLITE_TCLAPI testExpertDel(void *clientData){ + sqlite3expert *pExpert = (sqlite3expert*)clientData; + sqlite3_expert_destroy(pExpert); +} + +/* +** sqlite3_expert_new DB +*/ +static int SQLITE_TCLAPI test_sqlite3_expert_new( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + static int iCmd = 0; + sqlite3 *db; + char *zCmd = 0; + char *zErr = 0; + sqlite3expert *pExpert; + int rc = TCL_OK; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( dbHandleFromObj(interp, objv[1], &db) ){ + return TCL_ERROR; + } + + zCmd = sqlite3_mprintf("sqlite3expert%d", ++iCmd); + if( zCmd==0 ){ + Tcl_AppendResult(interp, "out of memory", (char*)0); + return TCL_ERROR; + } + + pExpert = sqlite3_expert_new(db, &zErr); + if( pExpert==0 ){ + Tcl_AppendResult(interp, zErr, (char*)0); + rc = TCL_ERROR; + }else{ + void *p = (void*)pExpert; + Tcl_CreateObjCommand(interp, zCmd, testExpertCmd, p, testExpertDel); + Tcl_SetObjResult(interp, Tcl_NewStringObj(zCmd, -1)); + } + + sqlite3_free(zCmd); + sqlite3_free(zErr); + return rc; +} + +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + +int TestExpert_Init(Tcl_Interp *interp){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + struct Cmd { + const char *zCmd; + Tcl_ObjCmdProc *xProc; + } aCmd[] = { + { "sqlite3_expert_new", test_sqlite3_expert_new }, + }; + int i; + + for(i=0; izCmd, p->xProc, 0, 0); + } +#endif + return TCL_OK; +} + +#endif diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index f5145426e0..d0e6d9be21 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3808,7 +3808,7 @@ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; UNUSED_PARAMETER(iSavepoint); assert( ((Fts3Table *)pVtab)->inTransaction ); - assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); + assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint ); TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ rc = fts3SyncMethod(pVtab); @@ -3963,7 +3963,7 @@ int sqlite3Fts3Init(sqlite3 *db){ #ifdef SQLITE_TEST if( rc==SQLITE_OK ){ - rc = sqlite3Fts3ExprInitTestInterface(db); + rc = sqlite3Fts3ExprInitTestInterface(db, pHash); } #endif diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index c3cab9d821..077bad7f54 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -584,7 +584,7 @@ int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int, ); void sqlite3Fts3ExprFree(Fts3Expr *); #ifdef SQLITE_TEST -int sqlite3Fts3ExprInitTestInterface(sqlite3 *db); +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*); int sqlite3Fts3InitTerm(sqlite3 *db); #endif diff --git a/ext/fts3/fts3_expr.c b/ext/fts3/fts3_expr.c index 788e5021ec..9f42b44a71 100644 --- a/ext/fts3/fts3_expr.c +++ b/ext/fts3/fts3_expr.c @@ -1108,34 +1108,6 @@ void sqlite3Fts3ExprFree(Fts3Expr *pDel){ #include -/* -** Function to query the hash-table of tokenizers (see README.tokenizers). -*/ -static int queryTestTokenizer( - sqlite3 *db, - const char *zName, - const sqlite3_tokenizer_module **pp -){ - int rc; - sqlite3_stmt *pStmt; - const char zSql[] = "SELECT fts3_tokenizer(?)"; - - *pp = 0; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - - sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ - memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); - } - } - - return sqlite3_finalize(pStmt); -} - /* ** Return a pointer to a buffer containing a text representation of the ** expression passed as the first argument. The buffer is obtained from @@ -1203,12 +1175,12 @@ static char *exprToString(Fts3Expr *pExpr, char *zBuf){ ** ** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); */ -static void fts3ExprTest( +static void fts3ExprTestCommon( + int bRebalance, sqlite3_context *context, int argc, sqlite3_value **argv ){ - sqlite3_tokenizer_module const *pModule = 0; sqlite3_tokenizer *pTokenizer = 0; int rc; char **azCol = 0; @@ -1218,7 +1190,9 @@ static void fts3ExprTest( int ii; Fts3Expr *pExpr; char *zBuf = 0; - sqlite3 *db = sqlite3_context_db_handle(context); + Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context); + const char *zTokenizer = 0; + char *zErr = 0; if( argc<3 ){ sqlite3_result_error(context, @@ -1227,24 +1201,18 @@ static void fts3ExprTest( return; } - rc = queryTestTokenizer(db, - (const char *)sqlite3_value_text(argv[0]), &pModule); - if( rc==SQLITE_NOMEM ){ - sqlite3_result_error_nomem(context); - goto exprtest_out; - }else if( !pModule ){ - sqlite3_result_error(context, "No such tokenizer module", -1); - goto exprtest_out; + zTokenizer = (const char*)sqlite3_value_text(argv[0]); + rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_error(context, zErr, -1); + } + sqlite3_free(zErr); + return; } - rc = pModule->xCreate(0, 0, &pTokenizer); - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); - if( rc==SQLITE_NOMEM ){ - sqlite3_result_error_nomem(context); - goto exprtest_out; - } - pTokenizer->pModule = pModule; - zExpr = (const char *)sqlite3_value_text(argv[1]); nExpr = sqlite3_value_bytes(argv[1]); nCol = argc-2; @@ -1257,7 +1225,7 @@ static void fts3ExprTest( azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]); } - if( sqlite3_user_data(context) ){ + if( bRebalance ){ char *zDummy = 0; rc = sqlite3Fts3ExprParse( pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy @@ -1283,23 +1251,38 @@ static void fts3ExprTest( sqlite3Fts3ExprFree(pExpr); exprtest_out: - if( pModule && pTokenizer ){ - rc = pModule->xDestroy(pTokenizer); + if( pTokenizer ){ + rc = pTokenizer->pModule->xDestroy(pTokenizer); } sqlite3_free(azCol); } +static void fts3ExprTest( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3ExprTestCommon(0, context, argc, argv); +} +static void fts3ExprTestRebalance( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3ExprTestCommon(1, context, argc, argv); +} + /* ** Register the query expression parser test function fts3_exprtest() ** with database connection db. */ -int sqlite3Fts3ExprInitTestInterface(sqlite3* db){ +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){ int rc = sqlite3_create_function( - db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0 + db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0 ); if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", - -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0 + -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0 ); } return rc; diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index daf3399a43..0baf82b76e 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -1908,6 +1908,7 @@ static int fts3WriteSegment( sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); } return rc; } @@ -1964,6 +1965,7 @@ static int fts3WriteSegdir( sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 6); } return rc; } @@ -3443,6 +3445,7 @@ static void fts3UpdateDocTotals( sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); sqlite3_step(pStmt); *pRC = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); sqlite3_free(a); } @@ -4631,6 +4634,7 @@ static int fts3TruncateSegment( sqlite3_bind_int(pChomp, 4, iIdx); sqlite3_step(pChomp); rc = sqlite3_reset(pChomp); + sqlite3_bind_null(pChomp, 2); } } @@ -4710,6 +4714,7 @@ static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } return rc; @@ -5524,7 +5529,6 @@ int sqlite3Fts3UpdateMethod( ){ Fts3Table *p = (Fts3Table *)pVtab; int rc = SQLITE_OK; /* Return Code */ - int isRemove = 0; /* True for an UPDATE or DELETE */ u32 *aSzIns = 0; /* Sizes of inserted documents */ u32 *aSzDel = 0; /* Sizes of deleted documents */ int nChng = 0; /* Net change in number of documents */ @@ -5622,7 +5626,6 @@ int sqlite3Fts3UpdateMethod( if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); - isRemove = 1; } /* If this is an INSERT or UPDATE operation, insert the new record. */ @@ -5634,7 +5637,7 @@ int sqlite3Fts3UpdateMethod( rc = FTS_CORRUPT_VTAB; } } - if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){ + if( rc==SQLITE_OK ){ rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid); } if( rc==SQLITE_OK ){ diff --git a/ext/fts3/unicode/mkunicode.tcl b/ext/fts3/unicode/mkunicode.tcl index de89099122..84b8ddc80b 100644 --- a/ext/fts3/unicode/mkunicode.tcl +++ b/ext/fts3/unicode/mkunicode.tcl @@ -529,6 +529,263 @@ proc print_fold {zFunc} { puts "\}" } +proc code {txt} { + set txt [string trimright $txt] + set txt [string trimleft $txt "\n"] + set n [expr {[string length $txt] - [string length [string trim $txt]]}] + set ret "" + foreach L [split $txt "\n"] { + append ret "[string range $L $n end]\n" + } + return [uplevel "subst -nocommands {$ret}"] +} + +proc intarray {lInt} { + set ret "" + set n [llength $lInt] + for {set i 0} {$i < $n} {incr i 10} { + append ret "\n " + foreach int [lrange $lInt $i [expr $i+9]] { + append ret [format "%-7s" "$int, "] + } + } + append ret "\n " + set ret +} + +proc categories_switch {Cvar first lSecond} { + upvar $Cvar C + set ret "" + append ret "case '$first':\n" + append ret " switch( zCat\[1\] ){\n" + foreach s $lSecond { + append ret " case '$s': aArray\[$C($first$s)\] = 1; break;\n" + } + append ret " case '*': \n" + foreach s $lSecond { + append ret " aArray\[$C($first$s)\] = 1;\n" + } + append ret " break;\n" + append ret " default: return 1;" + append ret " }\n" + append ret " break;\n" +} + +# Argument is a list. Each element of which is itself a list of two elements: +# +# * the codepoint +# * the category +# +# List elements are sorted in order of codepoint. +# +proc print_categories {lMap} { + set categories { + Cc Cf Cn Cs + Ll Lm Lo Lt Lu + Mc Me Mn + Nd Nl No + Pc Pd Pe Pf Pi Po Ps + Sc Sk Sm So + Zl Zp Zs + + LC Co + } + + for {set i 0} {$i < [llength $categories]} {incr i} { + set C([lindex $categories $i]) [expr 1+$i] + } + + set caseC [categories_switch C C {c f n s o}] + set caseL [categories_switch C L {l m o t u C}] + set caseM [categories_switch C M {c e n}] + set caseN [categories_switch C N {d l o}] + set caseP [categories_switch C P {c d e f i o s}] + set caseS [categories_switch C S {c k m o}] + set caseZ [categories_switch C Z {l p s}] + + set nCat [expr [llength [array names C]] + 1] + puts [code { + int sqlite3Fts5UnicodeNCat(void) { + return $nCat; + } + + int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ + aArray[0] = 1; + switch( zCat[0] ){ + $caseC + $caseL + $caseM + $caseN + $caseP + $caseS + $caseZ + } + return 0; + } + }] + + set nRepeat 0 + set first [lindex $lMap 0 0] + set class [lindex $lMap 0 1] + set prev -1 + + set CASE(0) "Lu" + set CASE(1) "Ll" + + foreach m $lMap { + foreach {codepoint cl} $m {} + set codepoint [expr "0x$codepoint"] + if {$codepoint>=(1<<20)} continue + + set bNew 0 + if {$codepoint!=($prev+1)} { + set bNew 1 + } elseif { + $cl==$class || ($class=="LC" && $cl==$CASE([expr $nRepeat & 0x01])) + } { + incr nRepeat + } elseif {$class=="Lu" && $nRepeat==1 && $cl=="Ll"} { + set class LC + incr nRepeat + } else { + set bNew 1 + } + if {$bNew} { + lappend lEntries [list $first $class $nRepeat] + set nRepeat 1 + set first $codepoint + set class $cl + } + set prev $codepoint + } + if {$nRepeat>0} { + lappend lEntries [list $first $class $nRepeat] + } + + set aBlock [list 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] + set aMap [list] + foreach e $lEntries { + foreach {cp class nRepeat} $e {} + set block [expr ($cp>>16)] + if {$block>0 && [lindex $aBlock $block]==0} { + for {set i 1} {$i<=$block} {incr i} { + if {[lindex $aBlock $i]==0} { + lset aBlock $i [llength $aMap] + } + } + } + lappend aMap [expr {$cp & 0xFFFF}] + lappend aData [expr {($nRepeat << 5) + $C($class)}] + } + for {set i 1} {$i<[llength $aBlock]} {incr i} { + if {[lindex $aBlock $i]==0} { + lset aBlock $i [llength $aMap] + } + } + + set aBlockArray [intarray $aBlock] + set aMapArray [intarray $aMap] + set aDataArray [intarray $aData] + puts [code { + static u16 aFts5UnicodeBlock[] = {$aBlockArray}; + static u16 aFts5UnicodeMap[] = {$aMapArray}; + static u16 aFts5UnicodeData[] = {$aDataArray}; + + int sqlite3Fts5UnicodeCategory(int iCode) { + int iRes = -1; + int iHi; + int iLo; + int ret; + u16 iKey; + + if( iCode>=(1<<20) ){ + return 0; + } + iLo = aFts5UnicodeBlock[(iCode>>16)]; + iHi = aFts5UnicodeBlock[1+(iCode>>16)]; + iKey = (iCode & 0xFFFF); + while( iHi>iLo ){ + int iTest = (iHi + iLo) / 2; + assert( iTest>=iLo && iTest=aFts5UnicodeMap[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest; + } + } + + if( iRes<0 ) return 0; + if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0; + ret = aFts5UnicodeData[iRes] & 0x1F; + if( ret!=$C(LC) ) return ret; + return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? $C(Ll) : $C(Lu); + } + + void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ + int i = 0; + int iTbl = 0; + while( i<128 ){ + int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ]; + int n = (aFts5UnicodeData[iTbl] >> 5) + i; + for(; i<128 && i" puts "" puts "int main(int argc, char **argv)\{" - puts " int r1, r2;" + puts " int r1, r2, r3;" puts " int code;" + puts " r3 = 0;" puts " r1 = isalnum_test(&code);" puts " if( r1 ) printf(\"isalnum(): Problem with code %d\\n\",code);" puts " else printf(\"isalnum(): test passed\\n\");" puts " r2 = fold_test(&code);" puts " if( r2 ) printf(\"fold(): Problem with code %d\\n\",code);" puts " else printf(\"fold(): test passed\\n\");" - puts " return (r1 || r2);" + if {$::generate_fts5_code} { + puts " r3 = categories_test(&code);" + puts " if( r3 ) printf(\"categories(): Problem with code %d\\n\",code);" + puts " else printf(\"categories(): test passed\\n\");" + } + puts " return (r1 || r2 || r3);" puts "\}" } @@ -651,10 +914,18 @@ for {set i 0} {$i < [llength $argv]-2} {incr i} { print_fileheader +if {$::generate_test_code} { + puts "typedef unsigned short int u16;" + puts "typedef unsigned char u8;" + puts "#include " +} + # Print the isalnum() function to stdout. # set lRange [an_load_separator_ranges] -print_isalnum ${function_prefix}UnicodeIsalnum $lRange +if {$generate_fts5_code==0} { + print_isalnum ${function_prefix}UnicodeIsalnum $lRange +} # Leave a gap between the two generated C functions. # @@ -677,12 +948,21 @@ puts "" # print_fold ${function_prefix}UnicodeFold +if {$generate_fts5_code} { + puts "" + puts "" + print_categories [cc_load_unicodedata_text ${unicodedata.txt}] +} + # Print the test routines and main() function to stdout, if -test # was specified. # if {$::generate_test_code} { - print_test_isalnum ${function_prefix}UnicodeIsalnum $lRange + if {$generate_fts5_code==0} { + print_test_isalnum ${function_prefix}UnicodeIsalnum $lRange + } print_fold_test ${function_prefix}UnicodeFold $mappings + print_test_categories [cc_load_unicodedata_text ${unicodedata.txt}] print_test_main } diff --git a/ext/fts3/unicode/parseunicode.tcl b/ext/fts3/unicode/parseunicode.tcl index 0cb2c83a18..966d7bdd3a 100644 --- a/ext/fts3/unicode/parseunicode.tcl +++ b/ext/fts3/unicode/parseunicode.tcl @@ -143,4 +143,40 @@ proc tl_load_casefolding_txt {zName} { } } +proc cc_load_unicodedata_text {zName} { + set fd [open $zName] + set lField { + code + character_name + general_category + canonical_combining_classes + bidirectional_category + character_decomposition_mapping + decimal_digit_value + digit_value + numeric_value + mirrored + unicode_1_name + iso10646_comment_field + uppercase_mapping + lowercase_mapping + titlecase_mapping + } + set lRet [list] + + while { ![eof $fd] } { + set line [gets $fd] + if {$line == ""} continue + + set fields [split $line ";"] + if {[llength $fields] != [llength $lField]} { error "parse error: $line" } + foreach $lField $fields {} + + lappend lRet [list $code $general_category] + } + + close $fd + set lRet +} + diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index a45c145d38..037da64d42 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -444,7 +444,7 @@ struct Fts5ExtensionApi { ** This way, even if the tokenizer does not provide synonyms ** when tokenizing query text (it should not - to do would be ** inefficient), it doesn't matter if the user queries for -** 'first + place' or '1st + place', as there are entires in the +** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. ** ** @@ -472,7 +472,7 @@ struct Fts5ExtensionApi { ** extra data to the FTS index or require FTS5 to query for multiple terms, ** so it is efficient in terms of disk space and query speed. However, it ** does not support prefix queries very well. If, as suggested above, the -** token "first" is subsituted for "1st" by the tokenizer, then the query: +** token "first" is substituted for "1st" by the tokenizer, then the query: ** ** ** ... MATCH '1s*' diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 63dc082687..a460a7af34 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -722,6 +722,8 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm( int bPrefix ); +void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*); + Fts5ExprNearset *sqlite3Fts5ParseNearset( Fts5Parse*, Fts5ExprNearset*, @@ -782,9 +784,12 @@ int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*); /************************************************************************** ** Interface to automatically generated code in fts5_unicode2.c. */ -int sqlite3Fts5UnicodeIsalnum(int c); int sqlite3Fts5UnicodeIsdiacritic(int c); int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic); + +int sqlite3Fts5UnicodeCatParse(const char*, u8*); +int sqlite3Fts5UnicodeCategory(int iCode); +void sqlite3Fts5UnicodeAscii(u8*, u8*); /* ** End of interface to code in fts5_unicode2.c. **************************************************************************/ diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 219ea6fff8..594b981dda 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -358,6 +358,16 @@ static int fts5SnippetScore( return rc; } +/* +** Return the value in pVal interpreted as utf-8 text. Except, if pVal +** contains a NULL value, return a pointer to a static string zero +** bytes in length instead of a NULL pointer. +*/ +static const char *fts5ValueToText(sqlite3_value *pVal){ + const char *zRet = (const char*)sqlite3_value_text(pVal); + return zRet ? zRet : ""; +} + /* ** Implementation of snippet() function. */ @@ -393,9 +403,9 @@ static void fts5SnippetFunction( nCol = pApi->xColumnCount(pFts); memset(&ctx, 0, sizeof(HighlightContext)); iCol = sqlite3_value_int(apVal[0]); - ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); - ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); - zEllips = (const char*)sqlite3_value_text(apVal[3]); + ctx.zOpen = fts5ValueToText(apVal[1]); + ctx.zClose = fts5ValueToText(apVal[2]); + zEllips = fts5ValueToText(apVal[3]); nToken = sqlite3_value_int(apVal[4]); iBestCol = (iCol>=0 ? iCol : 0); diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index aa7141cfee..a09fe7def8 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -36,6 +36,7 @@ void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*); #include void sqlite3Fts5ParserTrace(FILE*, char*); #endif +int sqlite3Fts5ParserFallback(int); struct Fts5Expr { @@ -87,7 +88,8 @@ struct Fts5ExprNode { ** or term prefix. */ struct Fts5ExprTerm { - int bPrefix; /* True for a prefix term */ + u8 bPrefix; /* True for a prefix term */ + u8 bFirst; /* True if token must be first in column */ char *zTerm; /* nul-terminated term */ Fts5IndexIter *pIter; /* Iterator for this term */ Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */ @@ -168,6 +170,7 @@ static int fts5ExprGetToken( case '+': tok = FTS5_PLUS; break; case '*': tok = FTS5_STAR; break; case '-': tok = FTS5_MINUS; break; + case '^': tok = FTS5_CARET; break; case '\0': tok = FTS5_EOF; break; case '"': { @@ -427,6 +430,7 @@ static int fts5ExprPhraseIsMatch( Fts5PoslistReader *aIter = aStatic; int i; int rc = SQLITE_OK; + int bFirst = pPhrase->aTerm[0].bFirst; fts5BufferZero(&pPhrase->poslist); @@ -481,8 +485,10 @@ static int fts5ExprPhraseIsMatch( }while( bMatch==0 ); /* Append position iPos to the output */ - rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos); - if( rc!=SQLITE_OK ) goto ismatch_out; + if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){ + rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos); + if( rc!=SQLITE_OK ) goto ismatch_out; + } for(i=0; inTerm; i++){ if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out; @@ -736,7 +742,9 @@ static int fts5ExprNearTest( ** phrase is not a match, break out of the loop early. */ for(i=0; rc==SQLITE_OK && inPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; - if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){ + if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym + || pNear->pColset || pPhrase->aTerm[0].bFirst + ){ int bMatch = 0; rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch); if( bMatch==0 ) break; @@ -917,6 +925,7 @@ static int fts5ExprNodeTest_STRING( assert( pNear->nPhrase>1 || pNear->apPhrase[0]->nTerm>1 || pNear->apPhrase[0]->aTerm[0].pSynonym + || pNear->apPhrase[0]->aTerm[0].bFirst ); /* Initialize iLast, the "lastest" rowid any iterator points to. If the @@ -1441,6 +1450,16 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ } } +/* +** Set the "bFirst" flag on the first token of the phrase passed as the +** only argument. +*/ +void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){ + if( pPhrase && pPhrase->nTerm ){ + pPhrase->aTerm[0].bFirst = 1; + } +} + /* ** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated ** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is @@ -1658,7 +1677,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm( ** no token characters at all. (e.g ... MATCH '""'). */ sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); }else if( sCtx.pPhrase->nTerm ){ - sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix; + sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } @@ -1719,6 +1738,7 @@ int sqlite3Fts5ExprClonePhrase( } if( rc==SQLITE_OK ){ sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; + sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; } } }else{ @@ -1737,7 +1757,10 @@ int sqlite3Fts5ExprClonePhrase( pNew->pRoot->pNear->nPhrase = 1; sCtx.pPhrase->pNode = pNew->pRoot; - if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){ + if( pOrig->nTerm==1 + && pOrig->aTerm[0].pSynonym==0 + && pOrig->aTerm[0].bFirst==0 + ){ pNew->pRoot->eType = FTS5_TERM; pNew->pRoot->xNext = fts5ExprNodeNext_TERM; }else{ @@ -2011,6 +2034,7 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ Fts5ExprNearset *pNear = pNode->pNear; if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 && pNear->apPhrase[0]->aTerm[0].pSynonym==0 + && pNear->apPhrase[0]->aTerm[0].bFirst==0 ){ pNode->eType = FTS5_TERM; pNode->xNext = fts5ExprNodeNext_TERM; @@ -2097,20 +2121,23 @@ Fts5ExprNode *sqlite3Fts5ParseNode( } } - if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL - && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1) - ){ - assert( pParse->rc==SQLITE_OK ); - pParse->rc = SQLITE_ERROR; - assert( pParse->zErr==0 ); - pParse->zErr = sqlite3_mprintf( - "fts5: %s queries are not supported (detail!=full)", - pNear->nPhrase==1 ? "phrase": "NEAR" - ); - sqlite3_free(pRet); - pRet = 0; + if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ + Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; + if( pNear->nPhrase!=1 + || pPhrase->nTerm>1 + || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) + ){ + assert( pParse->rc==SQLITE_OK ); + pParse->rc = SQLITE_ERROR; + assert( pParse->zErr==0 ); + pParse->zErr = sqlite3_mprintf( + "fts5: %s queries are not supported (detail!=full)", + pNear->nPhrase==1 ? "phrase": "NEAR" + ); + sqlite3_free(pRet); + pRet = 0; + } } - }else{ fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); @@ -2514,14 +2541,19 @@ static void fts5ExprIsAlnum( sqlite3_value **apVal /* Function arguments */ ){ int iCode; + u8 aArr[32]; if( nArg!=1 ){ sqlite3_result_error(pCtx, "wrong number of arguments to function fts5_isalnum", -1 ); return; } + memset(aArr, 0, sizeof(aArr)); + sqlite3Fts5UnicodeCatParse("L*", aArr); + sqlite3Fts5UnicodeCatParse("N*", aArr); + sqlite3Fts5UnicodeCatParse("Co", aArr); iCode = sqlite3_value_int(apVal[0]); - sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode)); + sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]); } static void fts5ExprFold( @@ -2565,10 +2597,12 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } - /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */ + /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and + ** sqlite3Fts5ParserFallback() are unused */ #ifndef NDEBUG (void)sqlite3Fts5ParserTrace; #endif + (void)sqlite3Fts5ParserFallback; return rc; } diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index c94122838d..394280b3f2 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -758,6 +758,7 @@ static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){ sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC); sqlite3_step(p->pWriter); p->rc = sqlite3_reset(p->pWriter); + sqlite3_bind_null(p->pWriter, 2); } /* @@ -2386,6 +2387,7 @@ static void fts5SegIterSeekInit( bDlidx = (val & 0x0001); } p->rc = sqlite3_reset(pIdxSelect); + sqlite3_bind_null(pIdxSelect, 2); if( iPgpgnoFirst ){ iPg = pSeg->pgnoFirst; @@ -3598,6 +3600,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); p->rc = sqlite3_reset(pIdxSelect); + sqlite3_bind_null(pIdxSelect, 2); } } #endif @@ -3724,6 +3727,7 @@ static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){ sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1)); sqlite3_step(p->pIdxWriter); p->rc = sqlite3_reset(p->pIdxWriter); + sqlite3_bind_null(p->pIdxWriter, 2); } pWriter->iBtPage = 0; } @@ -4909,7 +4913,13 @@ static void fts5MergePrefixLists( Fts5Buffer out = {0, 0, 0}; Fts5Buffer tmp = {0, 0, 0}; - if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return; + /* The maximum size of the output is equal to the sum of the two + ** input sizes + 1 varint (9 bytes). The extra varint is because if the + ** first rowid in one input is a large negative number, and the first in + ** the other a non-negative number, the delta for the non-negative + ** number will be larger on disk than the literal integer value + ** was. */ + if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return; fts5DoclistIterInit(p1, &i1); fts5DoclistIterInit(p2, &i2); @@ -5003,6 +5013,7 @@ static void fts5MergePrefixLists( fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); } + assert( out.n<=(p1->n+p2->n+9) ); fts5BufferSet(&p->rc, p1, out.n, out.p); fts5BufferFree(&tmp); @@ -5250,7 +5261,10 @@ int sqlite3Fts5IndexCharlenToBytelen( for(i=0; i=nByte ) return 0; /* Input contains fewer than nChar chars */ if( (unsigned char)p[n++]>=0xc0 ){ - while( (p[n] & 0xc0)==0x80 ) n++; + while( (p[n] & 0xc0)==0x80 ){ + n++; + if( n>=nByte ) break; + } } } return n; diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index d59cd5b7cc..e9ec2de3a4 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -280,7 +280,7 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){ case FTS5_SAVEPOINT: assert( p->ts.eState==1 ); assert( iSavepoint>=0 ); - assert( iSavepoint>p->ts.iSavepoint ); + assert( iSavepoint>=p->ts.iSavepoint ); p->ts.iSavepoint = iSavepoint; break; @@ -535,6 +535,12 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ aColMap[1] = nCol; aColMap[2] = nCol+1; + assert( SQLITE_INDEX_CONSTRAINT_EQnConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; @@ -553,11 +559,11 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ pInfo->estimatedCost = 1e50; return SQLITE_OK; } - }else{ + }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){ int j; for(j=1; jiCol] && p->op & pC->op && p->usable ){ + if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){ pC->iConsIndex = i; idxFlags |= pC->fts5op; } @@ -1199,6 +1205,13 @@ static int fts5FilterMethod( assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 ); assert( pCsr->iLastRowid==LARGEST_INT64 ); assert( pCsr->iFirstRowid==SMALLEST_INT64 ); + if( pTab->pSortCsr->bDesc ){ + pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid; + pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid; + }else{ + pCsr->iLastRowid = pTab->pSortCsr->iLastRowid; + pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid; + } pCsr->ePlan = FTS5_PLAN_SOURCE; pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 59336fc7ac..70d7135113 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -458,6 +458,7 @@ static int fts5StorageInsertDocsize( sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } } return rc; @@ -1118,6 +1119,7 @@ int sqlite3Fts5StorageConfigValue( } sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 1); } if( rc==SQLITE_OK && pVal ){ int iNew = p->pConfig->iCookie + 1; diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index e8d4c32a46..f33dcae033 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -433,7 +433,7 @@ static int SQLITE_TCLAPI xF5tApi( int iVal; int bClear; if( Tcl_GetBooleanFromObj(interp, objv[2], &bClear) ) return TCL_ERROR; - iVal = ((char*)p->pApi->xGetAuxdata(p->pFts, bClear) - (char*)0); + iVal = (int)((char*)p->pApi->xGetAuxdata(p->pFts, bClear) - (char*)0); Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal)); break; } @@ -482,7 +482,7 @@ static int SQLITE_TCLAPI xF5tApi( rc = p->pApi->xPhraseFirstColumn(p->pFts, iPhrase, &iter, &iCol); if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); + Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE); return TCL_ERROR; } for( ; iCol>=0; p->pApi->xPhraseNextColumn(p->pFts, &iter, &iCol)){ @@ -924,7 +924,7 @@ static int SQLITE_TCLAPI f5tTokenizerReturn( rc = p->xToken(p->pCtx, tflags, zToken, nToken, iStart, iEnd); Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE); - return TCL_OK; + return rc==SQLITE_OK ? TCL_OK : TCL_ERROR; usage: Tcl_WrongNumArgs(interp, 1, objv, "?-colocated? TEXT START END"); diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c index b72a0c24ab..af2bc222f2 100644 --- a/ext/fts5/fts5_tokenize.c +++ b/ext/fts5/fts5_tokenize.c @@ -237,6 +237,8 @@ struct Unicode61Tokenizer { int bRemoveDiacritic; /* True if remove_diacritics=1 is set */ int nException; int *aiException; + + unsigned char aCategory[32]; /* True for token char categories */ }; static int fts5UnicodeAddExceptions( @@ -261,7 +263,7 @@ static int fts5UnicodeAddExceptions( if( iCode<128 ){ p->aTokenChar[iCode] = (unsigned char)bTokenChars; }else{ - bToken = sqlite3Fts5UnicodeIsalnum(iCode); + bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]; assert( (bToken==0 || bToken==1) ); assert( (bTokenChars==0 || bTokenChars==1) ); if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){ @@ -322,6 +324,21 @@ static void fts5UnicodeDelete(Fts5Tokenizer *pTok){ return; } +static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){ + const char *z = zCat; + + while( *z ){ + while( *z==' ' || *z=='\t' ) z++; + if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){ + return SQLITE_ERROR; + } + while( *z!=' ' && *z!='\t' && *z!='\0' ) z++; + } + + sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar); + return SQLITE_OK; +} + /* ** Create a "unicode61" tokenizer. */ @@ -340,15 +357,28 @@ static int fts5UnicodeCreate( }else{ p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer)); if( p ){ + const char *zCat = "L* N* Co"; int i; memset(p, 0, sizeof(Unicode61Tokenizer)); - memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); + p->bRemoveDiacritic = 1; p->nFold = 64; p->aFold = sqlite3_malloc(p->nFold * sizeof(char)); if( p->aFold==0 ){ rc = SQLITE_NOMEM; } + + /* Search for a "categories" argument */ + for(i=0; rc==SQLITE_OK && iaCategory[sqlite3Fts5UnicodeCategory(iCode)] + ^ fts5UnicodeIsException(p, iCode) + ); } static int fts5UnicodeTokenize( diff --git a/ext/fts5/fts5_unicode2.c b/ext/fts5/fts5_unicode2.c index 1ef56f6156..8c48aaa49b 100644 --- a/ext/fts5/fts5_unicode2.c +++ b/ext/fts5/fts5_unicode2.c @@ -18,135 +18,6 @@ #include -/* -** Return true if the argument corresponds to a unicode codepoint -** classified as either a letter or a number. Otherwise false. -** -** The results are undefined if the value passed to this function -** is less than zero. -*/ -int sqlite3Fts5UnicodeIsalnum(int c){ - /* Each unsigned integer in the following array corresponds to a contiguous - ** range of unicode codepoints that are not either letters or numbers (i.e. - ** codepoints for which this function should return 0). - ** - ** The most significant 22 bits in each 32-bit value contain the first - ** codepoint in the range. The least significant 10 bits are used to store - ** the size of the range (always at least 1). In other words, the value - ** ((C<<22) + N) represents a range of N codepoints starting with codepoint - ** C. It is not possible to represent a range larger than 1023 codepoints - ** using this format. - */ - static const unsigned int aEntry[] = { - 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, - 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, - 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, - 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, - 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, - 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, - 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, - 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, - 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, - 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, - 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, - 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, - 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, - 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, - 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, - 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, - 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, - 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, - 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, - 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, - 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, - 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, - 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, - 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, - 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, - 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, - 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, - 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, - 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, - 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, - 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, - 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, - 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, - 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, - 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, - 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, - 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, - 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, - 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, - 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, - 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, - 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, - 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, - 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, - 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, - 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, - 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, - 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, - 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, - 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, - 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, - 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, - 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, - 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, - 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, - 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, - 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, - 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, - 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, - 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, - 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, - 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, - 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013, - 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, - 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, - 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01, - 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403, - 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, - 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003, - 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003, - 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E, - 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046, - 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, - 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, - 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, - 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C, - 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002, - 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025, - 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6, - 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46, - 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060, - 0x380400F0, - }; - static const unsigned int aAscii[4] = { - 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, - }; - - if( (unsigned int)c<128 ){ - return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); - }else if( (unsigned int)c<(1<<22) ){ - unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; - int iRes = 0; - int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; - int iLo = 0; - while( iHi>=iLo ){ - int iTest = (iHi + iLo) / 2; - if( key >= aEntry[iTest] ){ - iRes = iTest; - iLo = iTest+1; - }else{ - iHi = iTest-1; - } - } - assert( aEntry[0]=aEntry[iRes] ); - return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); - } - return 1; -} /* @@ -358,3 +229,536 @@ int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){ return ret; } + + +#if 0 +int sqlite3Fts5UnicodeNCat(void) { + return 32; +} +#endif + +int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ + aArray[0] = 1; + switch( zCat[0] ){ + case 'C': + switch( zCat[1] ){ + case 'c': aArray[1] = 1; break; + case 'f': aArray[2] = 1; break; + case 'n': aArray[3] = 1; break; + case 's': aArray[4] = 1; break; + case 'o': aArray[31] = 1; break; + case '*': + aArray[1] = 1; + aArray[2] = 1; + aArray[3] = 1; + aArray[4] = 1; + aArray[31] = 1; + break; + default: return 1; } + break; + + case 'L': + switch( zCat[1] ){ + case 'l': aArray[5] = 1; break; + case 'm': aArray[6] = 1; break; + case 'o': aArray[7] = 1; break; + case 't': aArray[8] = 1; break; + case 'u': aArray[9] = 1; break; + case 'C': aArray[30] = 1; break; + case '*': + aArray[5] = 1; + aArray[6] = 1; + aArray[7] = 1; + aArray[8] = 1; + aArray[9] = 1; + aArray[30] = 1; + break; + default: return 1; } + break; + + case 'M': + switch( zCat[1] ){ + case 'c': aArray[10] = 1; break; + case 'e': aArray[11] = 1; break; + case 'n': aArray[12] = 1; break; + case '*': + aArray[10] = 1; + aArray[11] = 1; + aArray[12] = 1; + break; + default: return 1; } + break; + + case 'N': + switch( zCat[1] ){ + case 'd': aArray[13] = 1; break; + case 'l': aArray[14] = 1; break; + case 'o': aArray[15] = 1; break; + case '*': + aArray[13] = 1; + aArray[14] = 1; + aArray[15] = 1; + break; + default: return 1; } + break; + + case 'P': + switch( zCat[1] ){ + case 'c': aArray[16] = 1; break; + case 'd': aArray[17] = 1; break; + case 'e': aArray[18] = 1; break; + case 'f': aArray[19] = 1; break; + case 'i': aArray[20] = 1; break; + case 'o': aArray[21] = 1; break; + case 's': aArray[22] = 1; break; + case '*': + aArray[16] = 1; + aArray[17] = 1; + aArray[18] = 1; + aArray[19] = 1; + aArray[20] = 1; + aArray[21] = 1; + aArray[22] = 1; + break; + default: return 1; } + break; + + case 'S': + switch( zCat[1] ){ + case 'c': aArray[23] = 1; break; + case 'k': aArray[24] = 1; break; + case 'm': aArray[25] = 1; break; + case 'o': aArray[26] = 1; break; + case '*': + aArray[23] = 1; + aArray[24] = 1; + aArray[25] = 1; + aArray[26] = 1; + break; + default: return 1; } + break; + + case 'Z': + switch( zCat[1] ){ + case 'l': aArray[27] = 1; break; + case 'p': aArray[28] = 1; break; + case 's': aArray[29] = 1; break; + case '*': + aArray[27] = 1; + aArray[28] = 1; + aArray[29] = 1; + break; + default: return 1; } + break; + + } + return 0; +} + +static u16 aFts5UnicodeBlock[] = { + 0, 1471, 1753, 1760, 1760, 1760, 1760, 1760, 1760, 1760, + 1760, 1760, 1760, 1760, 1760, 1763, 1765, + }; +static u16 aFts5UnicodeMap[] = { + 0, 32, 33, 36, 37, 40, 41, 42, 43, 44, + 45, 46, 48, 58, 60, 63, 65, 91, 92, 93, + 94, 95, 96, 97, 123, 124, 125, 126, 127, 160, + 161, 162, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 180, 181, 182, 184, 185, + 186, 187, 188, 191, 192, 215, 216, 223, 247, 248, + 256, 312, 313, 329, 330, 377, 383, 385, 387, 388, + 391, 394, 396, 398, 402, 403, 405, 406, 409, 412, + 414, 415, 417, 418, 423, 427, 428, 431, 434, 436, + 437, 440, 442, 443, 444, 446, 448, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 477, 478, 496, + 497, 498, 499, 500, 503, 505, 506, 564, 570, 572, + 573, 575, 577, 580, 583, 584, 592, 660, 661, 688, + 706, 710, 722, 736, 741, 748, 749, 750, 751, 768, + 880, 884, 885, 886, 890, 891, 894, 900, 902, 903, + 904, 908, 910, 912, 913, 931, 940, 975, 977, 978, + 981, 984, 1008, 1012, 1014, 1015, 1018, 1020, 1021, 1072, + 1120, 1154, 1155, 1160, 1162, 1217, 1231, 1232, 1329, 1369, + 1370, 1377, 1417, 1418, 1423, 1425, 1470, 1471, 1472, 1473, + 1475, 1476, 1478, 1479, 1488, 1520, 1523, 1536, 1542, 1545, + 1547, 1548, 1550, 1552, 1563, 1566, 1568, 1600, 1601, 1611, + 1632, 1642, 1646, 1648, 1649, 1748, 1749, 1750, 1757, 1758, + 1759, 1765, 1767, 1769, 1770, 1774, 1776, 1786, 1789, 1791, + 1792, 1807, 1808, 1809, 1810, 1840, 1869, 1958, 1969, 1984, + 1994, 2027, 2036, 2038, 2039, 2042, 2048, 2070, 2074, 2075, + 2084, 2085, 2088, 2089, 2096, 2112, 2137, 2142, 2208, 2210, + 2276, 2304, 2307, 2308, 2362, 2363, 2364, 2365, 2366, 2369, + 2377, 2381, 2382, 2384, 2385, 2392, 2402, 2404, 2406, 2416, + 2417, 2418, 2425, 2433, 2434, 2437, 2447, 2451, 2474, 2482, + 2486, 2492, 2493, 2494, 2497, 2503, 2507, 2509, 2510, 2519, + 2524, 2527, 2530, 2534, 2544, 2546, 2548, 2554, 2555, 2561, + 2563, 2565, 2575, 2579, 2602, 2610, 2613, 2616, 2620, 2622, + 2625, 2631, 2635, 2641, 2649, 2654, 2662, 2672, 2674, 2677, + 2689, 2691, 2693, 2703, 2707, 2730, 2738, 2741, 2748, 2749, + 2750, 2753, 2759, 2761, 2763, 2765, 2768, 2784, 2786, 2790, + 2800, 2801, 2817, 2818, 2821, 2831, 2835, 2858, 2866, 2869, + 2876, 2877, 2878, 2879, 2880, 2881, 2887, 2891, 2893, 2902, + 2903, 2908, 2911, 2914, 2918, 2928, 2929, 2930, 2946, 2947, + 2949, 2958, 2962, 2969, 2972, 2974, 2979, 2984, 2990, 3006, + 3008, 3009, 3014, 3018, 3021, 3024, 3031, 3046, 3056, 3059, + 3065, 3066, 3073, 3077, 3086, 3090, 3114, 3125, 3133, 3134, + 3137, 3142, 3146, 3157, 3160, 3168, 3170, 3174, 3192, 3199, + 3202, 3205, 3214, 3218, 3242, 3253, 3260, 3261, 3262, 3263, + 3264, 3270, 3271, 3274, 3276, 3285, 3294, 3296, 3298, 3302, + 3313, 3330, 3333, 3342, 3346, 3389, 3390, 3393, 3398, 3402, + 3405, 3406, 3415, 3424, 3426, 3430, 3440, 3449, 3450, 3458, + 3461, 3482, 3507, 3517, 3520, 3530, 3535, 3538, 3542, 3544, + 3570, 3572, 3585, 3633, 3634, 3636, 3647, 3648, 3654, 3655, + 3663, 3664, 3674, 3713, 3716, 3719, 3722, 3725, 3732, 3737, + 3745, 3749, 3751, 3754, 3757, 3761, 3762, 3764, 3771, 3773, + 3776, 3782, 3784, 3792, 3804, 3840, 3841, 3844, 3859, 3860, + 3861, 3864, 3866, 3872, 3882, 3892, 3893, 3894, 3895, 3896, + 3897, 3898, 3899, 3900, 3901, 3902, 3904, 3913, 3953, 3967, + 3968, 3973, 3974, 3976, 3981, 3993, 4030, 4038, 4039, 4046, + 4048, 4053, 4057, 4096, 4139, 4141, 4145, 4146, 4152, 4153, + 4155, 4157, 4159, 4160, 4170, 4176, 4182, 4184, 4186, 4190, + 4193, 4194, 4197, 4199, 4206, 4209, 4213, 4226, 4227, 4229, + 4231, 4237, 4238, 4239, 4240, 4250, 4253, 4254, 4256, 4295, + 4301, 4304, 4347, 4348, 4349, 4682, 4688, 4696, 4698, 4704, + 4746, 4752, 4786, 4792, 4800, 4802, 4808, 4824, 4882, 4888, + 4957, 4960, 4969, 4992, 5008, 5024, 5120, 5121, 5741, 5743, + 5760, 5761, 5787, 5788, 5792, 5867, 5870, 5888, 5902, 5906, + 5920, 5938, 5941, 5952, 5970, 5984, 5998, 6002, 6016, 6068, + 6070, 6071, 6078, 6086, 6087, 6089, 6100, 6103, 6104, 6107, + 6108, 6109, 6112, 6128, 6144, 6150, 6151, 6155, 6158, 6160, + 6176, 6211, 6212, 6272, 6313, 6314, 6320, 6400, 6432, 6435, + 6439, 6441, 6448, 6450, 6451, 6457, 6464, 6468, 6470, 6480, + 6512, 6528, 6576, 6593, 6600, 6608, 6618, 6622, 6656, 6679, + 6681, 6686, 6688, 6741, 6742, 6743, 6744, 6752, 6753, 6754, + 6755, 6757, 6765, 6771, 6783, 6784, 6800, 6816, 6823, 6824, + 6912, 6916, 6917, 6964, 6965, 6966, 6971, 6972, 6973, 6978, + 6979, 6981, 6992, 7002, 7009, 7019, 7028, 7040, 7042, 7043, + 7073, 7074, 7078, 7080, 7082, 7083, 7084, 7086, 7088, 7098, + 7142, 7143, 7144, 7146, 7149, 7150, 7151, 7154, 7164, 7168, + 7204, 7212, 7220, 7222, 7227, 7232, 7245, 7248, 7258, 7288, + 7294, 7360, 7376, 7379, 7380, 7393, 7394, 7401, 7405, 7406, + 7410, 7412, 7413, 7424, 7468, 7531, 7544, 7545, 7579, 7616, + 7676, 7680, 7830, 7838, 7936, 7944, 7952, 7960, 7968, 7976, + 7984, 7992, 8000, 8008, 8016, 8025, 8027, 8029, 8031, 8033, + 8040, 8048, 8064, 8072, 8080, 8088, 8096, 8104, 8112, 8118, + 8120, 8124, 8125, 8126, 8127, 8130, 8134, 8136, 8140, 8141, + 8144, 8150, 8152, 8157, 8160, 8168, 8173, 8178, 8182, 8184, + 8188, 8189, 8192, 8203, 8208, 8214, 8216, 8217, 8218, 8219, + 8221, 8222, 8223, 8224, 8232, 8233, 8234, 8239, 8240, 8249, + 8250, 8251, 8255, 8257, 8260, 8261, 8262, 8263, 8274, 8275, + 8276, 8277, 8287, 8288, 8298, 8304, 8305, 8308, 8314, 8317, + 8318, 8319, 8320, 8330, 8333, 8334, 8336, 8352, 8400, 8413, + 8417, 8418, 8421, 8448, 8450, 8451, 8455, 8456, 8458, 8459, + 8462, 8464, 8467, 8468, 8469, 8470, 8472, 8473, 8478, 8484, + 8485, 8486, 8487, 8488, 8489, 8490, 8494, 8495, 8496, 8500, + 8501, 8505, 8506, 8508, 8510, 8512, 8517, 8519, 8522, 8523, + 8524, 8526, 8527, 8528, 8544, 8579, 8581, 8585, 8592, 8597, + 8602, 8604, 8608, 8609, 8611, 8612, 8614, 8615, 8622, 8623, + 8654, 8656, 8658, 8659, 8660, 8661, 8692, 8960, 8968, 8972, + 8992, 8994, 9001, 9002, 9003, 9084, 9085, 9115, 9140, 9180, + 9186, 9216, 9280, 9312, 9372, 9450, 9472, 9655, 9656, 9665, + 9666, 9720, 9728, 9839, 9840, 9985, 10088, 10089, 10090, 10091, + 10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, + 10102, 10132, 10176, 10181, 10182, 10183, 10214, 10215, 10216, 10217, + 10218, 10219, 10220, 10221, 10222, 10223, 10224, 10240, 10496, 10627, + 10628, 10629, 10630, 10631, 10632, 10633, 10634, 10635, 10636, 10637, + 10638, 10639, 10640, 10641, 10642, 10643, 10644, 10645, 10646, 10647, + 10648, 10649, 10712, 10713, 10714, 10715, 10716, 10748, 10749, 10750, + 11008, 11056, 11077, 11079, 11088, 11264, 11312, 11360, 11363, 11365, + 11367, 11374, 11377, 11378, 11380, 11381, 11383, 11388, 11390, 11393, + 11394, 11492, 11493, 11499, 11503, 11506, 11513, 11517, 11518, 11520, + 11559, 11565, 11568, 11631, 11632, 11647, 11648, 11680, 11688, 11696, + 11704, 11712, 11720, 11728, 11736, 11744, 11776, 11778, 11779, 11780, + 11781, 11782, 11785, 11786, 11787, 11788, 11789, 11790, 11799, 11800, + 11802, 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812, + 11813, 11814, 11815, 11816, 11817, 11818, 11823, 11824, 11834, 11904, + 11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294, 12295, 12296, + 12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12306, + 12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, + 12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342, 12344, 12347, + 12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447, 12448, 12449, + 12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694, 12704, 12736, + 12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896, 12928, 12938, + 12977, 12992, 13056, 13312, 19893, 19904, 19968, 40908, 40960, 40981, + 40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509, 42512, 42528, + 42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622, 42623, 42624, + 42655, 42656, 42726, 42736, 42738, 42752, 42775, 42784, 42786, 42800, + 42802, 42864, 42865, 42873, 42878, 42888, 42889, 42891, 42896, 42912, + 43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020, 43043, + 43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124, 43136, + 43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259, 43264, + 43274, 43302, 43310, 43312, 43335, 43346, 43359, 43360, 43392, 43395, + 43396, 43443, 43444, 43446, 43450, 43452, 43453, 43457, 43471, 43472, + 43486, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588, + 43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643, + 43648, 43696, 43697, 43698, 43701, 43703, 43705, 43710, 43712, 43713, + 43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758, 43760, 43762, + 43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816, 43968, 44003, + 44005, 44006, 44008, 44009, 44011, 44012, 44013, 44016, 44032, 55203, + 55216, 55243, 55296, 56191, 56319, 57343, 57344, 63743, 63744, 64112, + 64256, 64275, 64285, 64286, 64287, 64297, 64298, 64312, 64318, 64320, + 64323, 64326, 64434, 64467, 64830, 64831, 64848, 64914, 65008, 65020, + 65021, 65024, 65040, 65047, 65048, 65049, 65056, 65072, 65073, 65075, + 65077, 65078, 65079, 65080, 65081, 65082, 65083, 65084, 65085, 65086, + 65087, 65088, 65089, 65090, 65091, 65092, 65093, 65095, 65096, 65097, + 65101, 65104, 65108, 65112, 65113, 65114, 65115, 65116, 65117, 65118, + 65119, 65122, 65123, 65124, 65128, 65129, 65130, 65136, 65142, 65279, + 65281, 65284, 65285, 65288, 65289, 65290, 65291, 65292, 65293, 65294, + 65296, 65306, 65308, 65311, 65313, 65339, 65340, 65341, 65342, 65343, + 65344, 65345, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, + 65379, 65380, 65382, 65392, 65393, 65438, 65440, 65474, 65482, 65490, + 65498, 65504, 65506, 65507, 65508, 65509, 65512, 65513, 65517, 65529, + 65532, 0, 13, 40, 60, 63, 80, 128, 256, 263, + 311, 320, 373, 377, 394, 400, 464, 509, 640, 672, + 768, 800, 816, 833, 834, 842, 896, 927, 928, 968, + 976, 977, 1024, 1064, 1104, 1184, 2048, 2056, 2058, 2103, + 2108, 2111, 2135, 2136, 2304, 2326, 2335, 2336, 2367, 2432, + 2494, 2560, 2561, 2565, 2572, 2576, 2581, 2585, 2616, 2623, + 2624, 2640, 2656, 2685, 2687, 2816, 2873, 2880, 2904, 2912, + 2936, 3072, 3680, 4096, 4097, 4098, 4099, 4152, 4167, 4178, + 4198, 4224, 4226, 4227, 4272, 4275, 4279, 4281, 4283, 4285, + 4286, 4304, 4336, 4352, 4355, 4391, 4396, 4397, 4406, 4416, + 4480, 4482, 4483, 4531, 4534, 4543, 4545, 4549, 4560, 5760, + 5803, 5804, 5805, 5806, 5808, 5814, 5815, 5824, 8192, 9216, + 9328, 12288, 26624, 28416, 28496, 28497, 28559, 28563, 45056, 53248, + 53504, 53545, 53605, 53607, 53610, 53613, 53619, 53627, 53635, 53637, + 53644, 53674, 53678, 53760, 53826, 53829, 54016, 54112, 54272, 54298, + 54324, 54350, 54358, 54376, 54402, 54428, 54430, 54434, 54437, 54441, + 54446, 54454, 54459, 54461, 54469, 54480, 54506, 54532, 54535, 54541, + 54550, 54558, 54584, 54587, 54592, 54598, 54602, 54610, 54636, 54662, + 54688, 54714, 54740, 54766, 54792, 54818, 54844, 54870, 54896, 54922, + 54952, 54977, 54978, 55003, 55004, 55010, 55035, 55036, 55061, 55062, + 55068, 55093, 55094, 55119, 55120, 55126, 55151, 55152, 55177, 55178, + 55184, 55209, 55210, 55235, 55236, 55242, 55246, 60928, 60933, 60961, + 60964, 60967, 60969, 60980, 60985, 60987, 60994, 60999, 61001, 61003, + 61005, 61009, 61012, 61015, 61017, 61019, 61021, 61023, 61025, 61028, + 61031, 61036, 61044, 61049, 61054, 61056, 61067, 61089, 61093, 61099, + 61168, 61440, 61488, 61600, 61617, 61633, 61649, 61696, 61712, 61744, + 61808, 61926, 61968, 62016, 62032, 62208, 62256, 62263, 62336, 62368, + 62406, 62432, 62464, 62528, 62530, 62713, 62720, 62784, 62800, 62971, + 63045, 63104, 63232, 0, 42710, 42752, 46900, 46912, 47133, 63488, + 1, 32, 256, 0, 65533, + }; +static u16 aFts5UnicodeData[] = { + 1025, 61, 117, 55, 117, 54, 50, 53, 57, 53, + 49, 85, 333, 85, 121, 85, 841, 54, 53, 50, + 56, 48, 56, 837, 54, 57, 50, 57, 1057, 61, + 53, 151, 58, 53, 56, 58, 39, 52, 57, 34, + 58, 56, 58, 57, 79, 56, 37, 85, 56, 47, + 39, 51, 111, 53, 745, 57, 233, 773, 57, 261, + 1822, 37, 542, 37, 1534, 222, 69, 73, 37, 126, + 126, 73, 69, 137, 37, 73, 37, 105, 101, 73, + 37, 73, 37, 190, 158, 37, 126, 126, 73, 37, + 126, 94, 37, 39, 94, 69, 135, 41, 40, 37, + 41, 40, 37, 41, 40, 37, 542, 37, 606, 37, + 41, 40, 37, 126, 73, 37, 1886, 197, 73, 37, + 73, 69, 126, 105, 37, 286, 2181, 39, 869, 582, + 152, 390, 472, 166, 248, 38, 56, 38, 568, 3596, + 158, 38, 56, 94, 38, 101, 53, 88, 41, 53, + 105, 41, 73, 37, 553, 297, 1125, 94, 37, 105, + 101, 798, 133, 94, 57, 126, 94, 37, 1641, 1541, + 1118, 58, 172, 75, 1790, 478, 37, 2846, 1225, 38, + 213, 1253, 53, 49, 55, 1452, 49, 44, 53, 76, + 53, 76, 53, 44, 871, 103, 85, 162, 121, 85, + 55, 85, 90, 364, 53, 85, 1031, 38, 327, 684, + 333, 149, 71, 44, 3175, 53, 39, 236, 34, 58, + 204, 70, 76, 58, 140, 71, 333, 103, 90, 39, + 469, 34, 39, 44, 967, 876, 2855, 364, 39, 333, + 1063, 300, 70, 58, 117, 38, 711, 140, 38, 300, + 38, 108, 38, 172, 501, 807, 108, 53, 39, 359, + 876, 108, 42, 1735, 44, 42, 44, 39, 106, 268, + 138, 44, 74, 39, 236, 327, 76, 85, 333, 53, + 38, 199, 231, 44, 74, 263, 71, 711, 231, 39, + 135, 44, 39, 106, 140, 74, 74, 44, 39, 42, + 71, 103, 76, 333, 71, 87, 207, 58, 55, 76, + 42, 199, 71, 711, 231, 71, 71, 71, 44, 106, + 76, 76, 108, 44, 135, 39, 333, 76, 103, 44, + 76, 42, 295, 103, 711, 231, 71, 167, 44, 39, + 106, 172, 76, 42, 74, 44, 39, 71, 76, 333, + 53, 55, 44, 74, 263, 71, 711, 231, 71, 167, + 44, 39, 42, 44, 42, 140, 74, 74, 44, 44, + 42, 71, 103, 76, 333, 58, 39, 207, 44, 39, + 199, 103, 135, 71, 39, 71, 71, 103, 391, 74, + 44, 74, 106, 106, 44, 39, 42, 333, 111, 218, + 55, 58, 106, 263, 103, 743, 327, 167, 39, 108, + 138, 108, 140, 76, 71, 71, 76, 333, 239, 58, + 74, 263, 103, 743, 327, 167, 44, 39, 42, 44, + 170, 44, 74, 74, 76, 74, 39, 71, 76, 333, + 71, 74, 263, 103, 1319, 39, 106, 140, 106, 106, + 44, 39, 42, 71, 76, 333, 207, 58, 199, 74, + 583, 775, 295, 39, 231, 44, 106, 108, 44, 266, + 74, 53, 1543, 44, 71, 236, 55, 199, 38, 268, + 53, 333, 85, 71, 39, 71, 39, 39, 135, 231, + 103, 39, 39, 71, 135, 44, 71, 204, 76, 39, + 167, 38, 204, 333, 135, 39, 122, 501, 58, 53, + 122, 76, 218, 333, 335, 58, 44, 58, 44, 58, + 44, 54, 50, 54, 50, 74, 263, 1159, 460, 42, + 172, 53, 76, 167, 364, 1164, 282, 44, 218, 90, + 181, 154, 85, 1383, 74, 140, 42, 204, 42, 76, + 74, 76, 39, 333, 213, 199, 74, 76, 135, 108, + 39, 106, 71, 234, 103, 140, 423, 44, 74, 76, + 202, 44, 39, 42, 333, 106, 44, 90, 1225, 41, + 41, 1383, 53, 38, 10631, 135, 231, 39, 135, 1319, + 135, 1063, 135, 231, 39, 135, 487, 1831, 135, 2151, + 108, 309, 655, 519, 346, 2727, 49, 19847, 85, 551, + 61, 839, 54, 50, 2407, 117, 110, 423, 135, 108, + 583, 108, 85, 583, 76, 423, 103, 76, 1671, 76, + 42, 236, 266, 44, 74, 364, 117, 38, 117, 55, + 39, 44, 333, 335, 213, 49, 149, 108, 61, 333, + 1127, 38, 1671, 1319, 44, 39, 2247, 935, 108, 138, + 76, 106, 74, 44, 202, 108, 58, 85, 333, 967, + 167, 1415, 554, 231, 74, 333, 47, 1114, 743, 76, + 106, 85, 1703, 42, 44, 42, 236, 44, 42, 44, + 74, 268, 202, 332, 44, 333, 333, 245, 38, 213, + 140, 42, 1511, 44, 42, 172, 42, 44, 170, 44, + 74, 231, 333, 245, 346, 300, 314, 76, 42, 967, + 42, 140, 74, 76, 42, 44, 74, 71, 333, 1415, + 44, 42, 76, 106, 44, 42, 108, 74, 149, 1159, + 266, 268, 74, 76, 181, 333, 103, 333, 967, 198, + 85, 277, 108, 53, 428, 42, 236, 135, 44, 135, + 74, 44, 71, 1413, 2022, 421, 38, 1093, 1190, 1260, + 140, 4830, 261, 3166, 261, 265, 197, 201, 261, 265, + 261, 265, 197, 201, 261, 41, 41, 41, 94, 229, + 265, 453, 261, 264, 261, 264, 261, 264, 165, 69, + 137, 40, 56, 37, 120, 101, 69, 137, 40, 120, + 133, 69, 137, 120, 261, 169, 120, 101, 69, 137, + 40, 88, 381, 162, 209, 85, 52, 51, 54, 84, + 51, 54, 52, 277, 59, 60, 162, 61, 309, 52, + 51, 149, 80, 117, 57, 54, 50, 373, 57, 53, + 48, 341, 61, 162, 194, 47, 38, 207, 121, 54, + 50, 38, 335, 121, 54, 50, 422, 855, 428, 139, + 44, 107, 396, 90, 41, 154, 41, 90, 37, 105, + 69, 105, 37, 58, 41, 90, 57, 169, 218, 41, + 58, 41, 58, 41, 58, 137, 58, 37, 137, 37, + 135, 37, 90, 69, 73, 185, 94, 101, 58, 57, + 90, 37, 58, 527, 1134, 94, 142, 47, 185, 186, + 89, 154, 57, 90, 57, 90, 57, 250, 57, 1018, + 89, 90, 57, 58, 57, 1018, 8601, 282, 153, 666, + 89, 250, 54, 50, 2618, 57, 986, 825, 1306, 217, + 602, 1274, 378, 1935, 2522, 719, 5882, 57, 314, 57, + 1754, 281, 3578, 57, 4634, 3322, 54, 50, 54, 50, + 54, 50, 54, 50, 54, 50, 54, 50, 54, 50, + 975, 1434, 185, 54, 50, 1017, 54, 50, 54, 50, + 54, 50, 54, 50, 54, 50, 537, 8218, 4217, 54, + 50, 54, 50, 54, 50, 54, 50, 54, 50, 54, + 50, 54, 50, 54, 50, 54, 50, 54, 50, 54, + 50, 2041, 54, 50, 54, 50, 1049, 54, 50, 8281, + 1562, 697, 90, 217, 346, 1513, 1509, 126, 73, 69, + 254, 105, 37, 94, 37, 94, 165, 70, 105, 37, + 3166, 37, 218, 158, 108, 94, 149, 47, 85, 1221, + 37, 37, 1799, 38, 53, 44, 743, 231, 231, 231, + 231, 231, 231, 231, 231, 1036, 85, 52, 51, 52, + 51, 117, 52, 51, 53, 52, 51, 309, 49, 85, + 49, 53, 52, 51, 85, 52, 51, 54, 50, 54, + 50, 54, 50, 54, 50, 181, 38, 341, 81, 858, + 2874, 6874, 410, 61, 117, 58, 38, 39, 46, 54, + 50, 54, 50, 54, 50, 54, 50, 54, 50, 90, + 54, 50, 54, 50, 54, 50, 54, 50, 49, 54, + 82, 58, 302, 140, 74, 49, 166, 90, 110, 38, + 39, 53, 90, 2759, 76, 88, 70, 39, 49, 2887, + 53, 102, 39, 1319, 3015, 90, 143, 346, 871, 1178, + 519, 1018, 335, 986, 271, 58, 495, 1050, 335, 1274, + 495, 2042, 8218, 39, 39, 2074, 39, 39, 679, 38, + 36583, 1786, 1287, 198, 85, 8583, 38, 117, 519, 333, + 71, 1502, 39, 44, 107, 53, 332, 53, 38, 798, + 44, 2247, 334, 76, 213, 760, 294, 88, 478, 69, + 2014, 38, 261, 190, 350, 38, 88, 158, 158, 382, + 70, 37, 231, 44, 103, 44, 135, 44, 743, 74, + 76, 42, 154, 207, 90, 55, 58, 1671, 149, 74, + 1607, 522, 44, 85, 333, 588, 199, 117, 39, 333, + 903, 268, 85, 743, 364, 74, 53, 935, 108, 42, + 1511, 44, 74, 140, 74, 44, 138, 437, 38, 333, + 85, 1319, 204, 74, 76, 74, 76, 103, 44, 263, + 44, 42, 333, 149, 519, 38, 199, 122, 39, 42, + 1543, 44, 39, 108, 71, 76, 167, 76, 39, 44, + 39, 71, 38, 85, 359, 42, 76, 74, 85, 39, + 70, 42, 44, 199, 199, 199, 231, 231, 1127, 74, + 44, 74, 44, 74, 53, 42, 44, 333, 39, 39, + 743, 1575, 36, 68, 68, 36, 63, 63, 11719, 3399, + 229, 165, 39, 44, 327, 57, 423, 167, 39, 71, + 71, 3463, 536, 11623, 54, 50, 2055, 1735, 391, 55, + 58, 524, 245, 54, 50, 53, 236, 53, 81, 80, + 54, 50, 54, 50, 54, 50, 54, 50, 54, 50, + 54, 50, 54, 50, 54, 50, 85, 54, 50, 149, + 112, 117, 149, 49, 54, 50, 54, 50, 54, 50, + 117, 57, 49, 121, 53, 55, 85, 167, 4327, 34, + 117, 55, 117, 54, 50, 53, 57, 53, 49, 85, + 333, 85, 121, 85, 841, 54, 53, 50, 56, 48, + 56, 837, 54, 57, 50, 57, 54, 50, 53, 54, + 50, 85, 327, 38, 1447, 70, 999, 199, 199, 199, + 103, 87, 57, 56, 58, 87, 58, 153, 90, 98, + 90, 391, 839, 615, 71, 487, 455, 3943, 117, 1455, + 314, 1710, 143, 570, 47, 410, 1466, 44, 935, 1575, + 999, 143, 551, 46, 263, 46, 967, 53, 1159, 263, + 53, 174, 1289, 1285, 2503, 333, 199, 39, 1415, 71, + 39, 743, 53, 271, 711, 207, 53, 839, 53, 1799, + 71, 39, 108, 76, 140, 135, 103, 871, 108, 44, + 271, 309, 935, 79, 53, 1735, 245, 711, 271, 615, + 271, 2343, 1007, 42, 44, 42, 1703, 492, 245, 655, + 333, 76, 42, 1447, 106, 140, 74, 76, 85, 34, + 149, 807, 333, 108, 1159, 172, 42, 268, 333, 149, + 76, 42, 1543, 106, 300, 74, 135, 149, 333, 1383, + 44, 42, 44, 74, 204, 42, 44, 333, 28135, 3182, + 149, 34279, 18215, 2215, 39, 1482, 140, 422, 71, 7898, + 1274, 1946, 74, 108, 122, 202, 258, 268, 90, 236, + 986, 140, 1562, 2138, 108, 58, 2810, 591, 841, 837, + 841, 229, 581, 841, 837, 41, 73, 41, 73, 137, + 265, 133, 37, 229, 357, 841, 837, 73, 137, 265, + 233, 837, 73, 137, 169, 41, 233, 837, 841, 837, + 841, 837, 841, 837, 841, 837, 841, 837, 841, 901, + 809, 57, 805, 57, 197, 809, 57, 805, 57, 197, + 809, 57, 805, 57, 197, 809, 57, 805, 57, 197, + 809, 57, 805, 57, 197, 94, 1613, 135, 871, 71, + 39, 39, 327, 135, 39, 39, 39, 39, 39, 39, + 103, 71, 39, 39, 39, 39, 39, 39, 71, 39, + 135, 231, 135, 135, 39, 327, 551, 103, 167, 551, + 89, 1434, 3226, 506, 474, 506, 506, 367, 1018, 1946, + 1402, 954, 1402, 314, 90, 1082, 218, 2266, 666, 1210, + 186, 570, 2042, 58, 5850, 154, 2010, 154, 794, 2266, + 378, 2266, 3738, 39, 39, 39, 39, 39, 39, 17351, + 34, 3074, 7692, 63, 63, + }; + +int sqlite3Fts5UnicodeCategory(int iCode) { + int iRes = -1; + int iHi; + int iLo; + int ret; + u16 iKey; + + if( iCode>=(1<<20) ){ + return 0; + } + iLo = aFts5UnicodeBlock[(iCode>>16)]; + iHi = aFts5UnicodeBlock[1+(iCode>>16)]; + iKey = (iCode & 0xFFFF); + while( iHi>iLo ){ + int iTest = (iHi + iLo) / 2; + assert( iTest>=iLo && iTest=aFts5UnicodeMap[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest; + } + } + + if( iRes<0 ) return 0; + if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0; + ret = aFts5UnicodeData[iRes] & 0x1F; + if( ret!=30 ) return ret; + return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9; +} + +void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ + int i = 0; + int iTbl = 0; + while( i<128 ){ + int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ]; + int n = (aFts5UnicodeData[iTbl] >> 5) + i; + for(; i<128 && i)); +** +** One row for each term instance in the database. */ @@ -44,7 +49,7 @@ struct Fts5VocabTable { char *zFts5Db; /* Db containing fts5 table */ sqlite3 *db; /* Database handle */ Fts5Global *pGlobal; /* FTS5 global object for this database */ - int eType; /* FTS5_VOCAB_COL or ROW */ + int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */ }; struct Fts5VocabCursor { @@ -64,16 +69,22 @@ struct Fts5VocabCursor { i64 *aCnt; i64 *aDoc; - /* Output values used by 'row' and 'col' tables */ + /* Output values used by all tables. */ i64 rowid; /* This table's current rowid value */ Fts5Buffer term; /* Current value of 'term' column */ + + /* Output values Used by 'instance' tables only */ + i64 iInstPos; + int iInstOff; }; -#define FTS5_VOCAB_COL 0 -#define FTS5_VOCAB_ROW 1 +#define FTS5_VOCAB_COL 0 +#define FTS5_VOCAB_ROW 1 +#define FTS5_VOCAB_INSTANCE 2 #define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt" #define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt" +#define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset" /* ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. @@ -101,6 +112,9 @@ static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){ if( sqlite3_stricmp(zCopy, "row")==0 ){ *peType = FTS5_VOCAB_ROW; }else + if( sqlite3_stricmp(zCopy, "instance")==0 ){ + *peType = FTS5_VOCAB_INSTANCE; + }else { *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy); rc = SQLITE_ERROR; @@ -161,7 +175,8 @@ static int fts5VocabInitVtab( ){ const char *azSchema[] = { "CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA ")", - "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")" + "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")", + "CREATE TABlE vocab(" FTS5_VOCAB_INST_SCHEMA ")" }; Fts5VocabTable *pRet = 0; @@ -235,6 +250,15 @@ static int fts5VocabCreateMethod( /* ** Implementation of the xBestIndex method. +** +** Only constraints of the form: +** +** term <= ? +** term == ? +** term >= ? +** +** are interpreted. Less-than and less-than-or-equal are treated +** identically, as are greater-than and greater-than-or-equal. */ static int fts5VocabBestIndexMethod( sqlite3_vtab *pUnused, @@ -378,6 +402,54 @@ static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){ return SQLITE_OK; } +static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){ + int rc = SQLITE_OK; + + if( sqlite3Fts5IterEof(pCsr->pIter) ){ + pCsr->bEof = 1; + }else{ + const char *zTerm; + int nTerm; + zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); + if( pCsr->nLeTerm>=0 ){ + int nCmp = MIN(nTerm, pCsr->nLeTerm); + int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp); + if( bCmp<0 || (bCmp==0 && pCsr->nLeTermbEof = 1; + } + } + + sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); + } + return rc; +} + +static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){ + int eDetail = pCsr->pConfig->eDetail; + int rc = SQLITE_OK; + Fts5IndexIter *pIter = pCsr->pIter; + i64 *pp = &pCsr->iInstPos; + int *po = &pCsr->iInstOff; + + while( eDetail==FTS5_DETAIL_NONE + || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) + ){ + pCsr->iInstPos = 0; + pCsr->iInstOff = 0; + + rc = sqlite3Fts5IterNextScan(pCsr->pIter); + if( rc==SQLITE_OK ){ + rc = fts5VocabInstanceNewTerm(pCsr); + if( eDetail==FTS5_DETAIL_NONE ) break; + } + if( rc ){ + pCsr->bEof = 1; + break; + } + } + + return rc; +} /* ** Advance the cursor to the next row in the table. @@ -390,13 +462,17 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ pCsr->rowid++; + if( pTab->eType==FTS5_VOCAB_INSTANCE ){ + return fts5VocabInstanceNext(pCsr); + } + if( pTab->eType==FTS5_VOCAB_COL ){ for(pCsr->iCol++; pCsr->iColiCol++){ if( pCsr->aDoc[pCsr->iCol] ) break; } } - if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){ + if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){ if( sqlite3Fts5IterEof(pCsr->pIter) ){ pCsr->bEof = 1; }else{ @@ -420,22 +496,26 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); while( rc==SQLITE_OK ){ + int eDetail = pCsr->pConfig->eDetail; const u8 *pPos; int nPos; /* Position list */ i64 iPos = 0; /* 64-bit position read from poslist */ int iOff = 0; /* Current offset within position list */ pPos = pCsr->pIter->pData; nPos = pCsr->pIter->nData; - switch( pCsr->pConfig->eDetail ){ - case FTS5_DETAIL_FULL: - pPos = pCsr->pIter->pData; - nPos = pCsr->pIter->nData; - if( pTab->eType==FTS5_VOCAB_ROW ){ + + switch( pTab->eType ){ + case FTS5_VOCAB_ROW: + if( eDetail==FTS5_DETAIL_FULL ){ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ pCsr->aCnt[0]++; } - pCsr->aDoc[0]++; - }else{ + } + pCsr->aDoc[0]++; + break; + + case FTS5_VOCAB_COL: + if( eDetail==FTS5_DETAIL_FULL ){ int iCol = -1; while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ int ii = FTS5_POS2COLUMN(iPos); @@ -449,13 +529,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ iCol = ii; } } - } - break; - - case FTS5_DETAIL_COLUMNS: - if( pTab->eType==FTS5_VOCAB_ROW ){ - pCsr->aDoc[0]++; - }else{ + }else if( eDetail==FTS5_DETAIL_COLUMNS ){ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){ assert_nc( iPos>=0 && iPos=nCol ){ @@ -464,18 +538,21 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ } pCsr->aDoc[iPos]++; } + }else{ + assert( eDetail==FTS5_DETAIL_NONE ); + pCsr->aDoc[0]++; } break; - default: - assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE ); - pCsr->aDoc[0]++; + default: + assert( pTab->eType==FTS5_VOCAB_INSTANCE ); break; } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IterNextScan(pCsr->pIter); } + if( pTab->eType==FTS5_VOCAB_INSTANCE ) break; if( rc==SQLITE_OK ){ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); @@ -505,7 +582,9 @@ static int fts5VocabFilterMethod( int nUnused, /* Number of elements in apVal */ sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ + Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; + int eType = pTab->eType; int rc = SQLITE_OK; int iVal = 0; @@ -545,11 +624,16 @@ static int fts5VocabFilterMethod( } } - if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){ + rc = fts5VocabInstanceNewTerm(pCsr); + } + if( rc==SQLITE_OK + && !pCsr->bEof + && (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE) + ){ rc = fts5VocabNextMethod(pCursor); } @@ -591,13 +675,41 @@ static int fts5VocabColumnMethod( }else{ iVal = pCsr->aCnt[pCsr->iCol]; } - }else{ + }else if( eType==FTS5_VOCAB_ROW ){ assert( iCol==1 || iCol==2 ); if( iCol==1 ){ iVal = pCsr->aDoc[0]; }else{ iVal = pCsr->aCnt[0]; } + }else{ + assert( eType==FTS5_VOCAB_INSTANCE ); + switch( iCol ){ + case 1: + sqlite3_result_int64(pCtx, pCsr->pIter->iRowid); + break; + case 2: { + int ii = -1; + if( eDetail==FTS5_DETAIL_FULL ){ + ii = FTS5_POS2COLUMN(pCsr->iInstPos); + }else if( eDetail==FTS5_DETAIL_COLUMNS ){ + ii = (int)pCsr->iInstPos; + } + if( ii>=0 && iipConfig->nCol ){ + const char *z = pCsr->pConfig->azCol[ii]; + sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); + } + break; + } + default: { + assert( iCol==3 ); + if( eDetail==FTS5_DETAIL_FULL ){ + int ii = FTS5_POS2OFFSET(pCsr->iInstPos); + sqlite3_result_int(pCtx, ii); + } + break; + } + } } if( iVal>0 ) sqlite3_result_int64(pCtx, iVal); diff --git a/ext/fts5/fts5parse.y b/ext/fts5/fts5parse.y index 1582909aa8..134125db1f 100644 --- a/ext/fts5/fts5parse.y +++ b/ext/fts5/fts5parse.y @@ -148,7 +148,11 @@ cnearset(A) ::= colset(X) COLON nearset(Y). { %destructor nearset { sqlite3Fts5ParseNearsetFree($$); } %destructor nearphrases { sqlite3Fts5ParseNearsetFree($$); } -nearset(A) ::= phrase(X). { A = sqlite3Fts5ParseNearset(pParse, 0, X); } +nearset(A) ::= phrase(Y). { A = sqlite3Fts5ParseNearset(pParse, 0, Y); } +nearset(A) ::= CARET phrase(Y). { + sqlite3Fts5ParseSetCaret(Y); + A = sqlite3Fts5ParseNearset(pParse, 0, Y); +} nearset(A) ::= STRING(X) LP nearphrases(Y) neardist_opt(Z) RP. { sqlite3Fts5ParseNear(pParse, &X); sqlite3Fts5ParseSetDistance(pParse, Y, &Z); @@ -189,6 +193,5 @@ phrase(A) ::= STRING(Y) star_opt(Z). { ** Optional "*" character. */ %type star_opt {int} - star_opt(A) ::= STAR. { A = 1; } star_opt(A) ::= . { A = 0; } diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index a3ea0afc28..6fa3ad8e63 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -591,7 +591,19 @@ do_execsql_test 22.1 { SELECT rowid FROM t9('a*') } {1} +#------------------------------------------------------------------------- +do_execsql_test 23.0 { + CREATE VIRTUAL TABLE t10 USING fts5(x, detail=%DETAIL%); + CREATE TABLE t11(x); +} +do_execsql_test 23.1 { + SELECT * FROM t11, t10 WHERE t11.x = t10.x AND t10.rowid IS NULL; +} +do_execsql_test 23.2 { + SELECT * FROM t11, t10 WHERE t10.rowid IS NULL; } +} +expand_all_sql db finish_test diff --git a/ext/fts5/test/fts5af.test b/ext/fts5/test/fts5af.test index fa4ebd2955..86c8f753fa 100644 --- a/ext/fts5/test/fts5af.test +++ b/ext/fts5/test/fts5af.test @@ -175,6 +175,16 @@ do_execsql_test 5.1 { SELECT snippet(p1, 0, '[', ']', '...', 6) FROM p1('x'); } {{[x] a a a a a...}} +do_execsql_test 5.2 { + SELECT snippet(p1, 0, '[', ']', NULL, 6) FROM p1('x'); +} {{[x] a a a a a}} +do_execsql_test 5.3 { + SELECT snippet(p1, 0, NULL, ']', '...', 6) FROM p1('x'); +} {{x] a a a a a...}} +do_execsql_test 5.4 { + SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x'); +} {{[x a a a a a...}} + } ;# foreach_detail_mode finish_test diff --git a/ext/fts5/test/fts5cat.test b/ext/fts5/test/fts5cat.test new file mode 100644 index 0000000000..483f64bfef --- /dev/null +++ b/ext/fts5/test/fts5cat.test @@ -0,0 +1,59 @@ +# 2016 Jan 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +source [file join [file dirname [info script]] fts5_common.tcl] +ifcapable !fts5 { finish_test ; return } +set ::testprefix fts5cat + + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize="unicode61 categories 'L*'"); + INSERT INTO t1 VALUES ('Unlike1option2values3and4column5names'); +} + +do_execsql_test 1.1 { + SELECT rowid FROM t1('option'); +} {1} + +do_execsql_test 1.2 { + CREATE VIRTUAL TABLE t2 USING fts5(x); + CREATE VIRTUAL TABLE t2t USING fts5vocab(t2, row); + + CREATE VIRTUAL TABLE t3 USING fts5( + x, tokenize="unicode61 categories 'L* N* Co Mn'" + ); + CREATE VIRTUAL TABLE t3t USING fts5vocab(t3, row); + + CREATE VIRTUAL TABLE t4 USING fts5( + x, tokenize="unicode61 categories 'L* N* Co M*'" + ); + CREATE VIRTUAL TABLE t4t USING fts5vocab(t4, row); + + INSERT INTO t2 VALUES ('สนามกีฬา'); + INSERT INTO t3 VALUES ('สนามกีฬา'); + INSERT INTO t4 VALUES ('สนามกีฬา'); +} + +do_execsql_test 1.3 { + SELECT * FROM t2t +} {สนามก 1 1 ฬา 1 1} + +do_execsql_test 1.4 { + SELECT * FROM t3t +} {สนามกีฬา 1 1} + +do_execsql_test 1.5 { + SELECT * FROM t4t +} {สนามกีฬา 1 1} + + +finish_test diff --git a/ext/fts5/test/fts5connect.test b/ext/fts5/test/fts5connect.test new file mode 100644 index 0000000000..c615d4c734 --- /dev/null +++ b/ext/fts5/test/fts5connect.test @@ -0,0 +1,247 @@ +# 2017 August 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + + + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5connect + +ifcapable !fts5 { + finish_test + return +} + +#------------------------------------------------------------------------- +# The tests in this file test the outcome of a schema-reset happening +# within the xConnect() method of an FTS5 table. At one point this +# was causing a problem in SQLite. Each test proceeds as follows: +# +# 1. Connection [db] opens the db and reads from some unrelated, non-FTS5 +# table causing SQLite to load the db schema into memory. +# +# 2. Connection [db2] opens the db and modifies the db schema. +# +# 3. Connection [db] reads or writes an existing fts5 table. That the +# schema has been modified is detected inside the fts5 xConnect() +# callback that is invoked by sqlite3_prepare(). +# +# 4. Verify that the statement in 3 has worked. SQLite should detect +# that the schema has changed and successfully prepare the +# statement against the new schema. +# +# Test plan: +# +# 1.*: Trigger the xConnect()/schema-reset using statements executed +# directly against an FTS5 table. +# +# 2.*: Using various statements executed by various BEFORE triggers. +# +# 3.*: Using various statements executed by various AFTER triggers. +# +# 4.*: Using various statements executed by various INSTEAD OF triggers. +# + + + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft1 USING fts5(a, b); + CREATE TABLE abc(x INTEGER PRIMARY KEY); + CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b); + + INSERT INTO ft1 VALUES('one', 'two'); + INSERT INTO ft1 VALUES('three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM ft1" {one two three four} + 2 "REPLACE INTO ft1(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft1" {five six three four} + 4 "INSERT INTO ft1 VALUES('seven', 'eight')" {} + 5 "SELECT * FROM ft1" {five six three four seven eight} + 6 "DELETE FROM ft1 WHERE rowid=2" {} + 7 "UPDATE ft1 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft1" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 1.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 1.$tn.2 $sql $res + + do_execsql_test 1.$tn.3 { + INSERT INTO ft1(ft1) VALUES('integrity-check'); + } +} + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft2 USING fts5(a, b); + CREATE TABLE t2(a, b); + CREATE TABLE log(txt); + + CREATE TRIGGER t2_ai AFTER INSERT ON t2 BEGIN + INSERT INTO ft2(rowid, a, b) VALUES(new.rowid, new.a, new.b); + INSERT INTO log VALUES('insert'); + END; + + CREATE TRIGGER t2_ad AFTER DELETE ON t2 BEGIN + DELETE FROM ft2 WHERE rowid = old.rowid; + INSERT INTO log VALUES('delete'); + END; + + CREATE TRIGGER t2_au AFTER UPDATE ON t2 BEGIN + UPDATE ft2 SET a=new.a, b=new.b WHERE rowid=new.rowid; + INSERT INTO log VALUES('update'); + END; + + INSERT INTO t2 VALUES('one', 'two'); + INSERT INTO t2 VALUES('three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM t2" {one two three four} + 2 "REPLACE INTO t2(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft2" {five six three four} + 4 "INSERT INTO t2 VALUES('seven', 'eight')" {} + 5 "SELECT * FROM ft2" {five six three four seven eight} + 6 "DELETE FROM t2 WHERE rowid=2" {} + 7 "UPDATE t2 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft2" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 2.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 2.$tn.2 $sql $res + + do_execsql_test 2.$tn.3 { + INSERT INTO ft2(ft2) VALUES('integrity-check'); + } +} + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE ft3 USING fts5(a, b); + CREATE TABLE t3(a, b); + + CREATE TRIGGER t3_ai BEFORE INSERT ON t3 BEGIN + INSERT INTO ft3(rowid, a, b) VALUES(new.rowid, new.a, new.b); + INSERT INTO log VALUES('insert'); + END; + + CREATE TRIGGER t3_ad BEFORE DELETE ON t3 BEGIN + DELETE FROM ft3 WHERE rowid = old.rowid; + INSERT INTO log VALUES('delete'); + END; + + CREATE TRIGGER t3_au BEFORE UPDATE ON t3 BEGIN + UPDATE ft3 SET a=new.a, b=new.b WHERE rowid=new.rowid; + INSERT INTO log VALUES('update'); + END; + + INSERT INTO t3(rowid, a, b) VALUES(1, 'one', 'two'); + INSERT INTO t3(rowid, a, b) VALUES(2, 'three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM t3" {one two three four} + 2 "REPLACE INTO t3(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft3" {five six three four} + 4 "INSERT INTO t3(rowid, a, b) VALUES(3, 'seven', 'eight')" {} + 5 "SELECT * FROM ft3" {five six three four seven eight} + 6 "DELETE FROM t3 WHERE rowid=2" {} + 7 "UPDATE t3 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft3" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 3.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 3.$tn.2 $sql $res + + do_execsql_test 3.$tn.3 { + INSERT INTO ft3(ft3) VALUES('integrity-check'); + } +} + +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE ft4 USING fts5(a, b); + CREATE VIEW v4 AS SELECT rowid, * FROM ft4; + + CREATE TRIGGER t4_ai INSTEAD OF INSERT ON v4 BEGIN + INSERT INTO ft4(rowid, a, b) VALUES(new.rowid, new.a, new.b); + INSERT INTO log VALUES('insert'); + END; + + CREATE TRIGGER t4_ad INSTEAD OF DELETE ON v4 BEGIN + DELETE FROM ft4 WHERE rowid = old.rowid; + INSERT INTO log VALUES('delete'); + END; + + CREATE TRIGGER t4_au INSTEAD OF UPDATE ON v4 BEGIN + UPDATE ft4 SET a=new.a, b=new.b WHERE rowid=new.rowid; + INSERT INTO log VALUES('update'); + END; + + INSERT INTO ft4(rowid, a, b) VALUES(1, 'one', 'two'); + INSERT INTO ft4(rowid, a, b) VALUES(2, 'three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM ft4" {one two three four} + 2 "REPLACE INTO v4(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft4" {five six three four} + 4 "INSERT INTO v4(rowid, a, b) VALUES(3, 'seven', 'eight')" {} + 5 "SELECT * FROM ft4" {five six three four seven eight} + 6 "DELETE FROM v4 WHERE rowid=2" {} + 7 "UPDATE v4 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft4" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 4.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 4.$tn.2 $sql $res + + do_execsql_test 4.$tn.3 { + INSERT INTO ft3(ft3) VALUES('integrity-check'); + } +} + +finish_test + diff --git a/ext/fts5/test/fts5fault6.test b/ext/fts5/test/fts5fault6.test index 1c1c9f20c1..a39063a356 100644 --- a/ext/fts5/test/fts5fault6.test +++ b/ext/fts5/test/fts5fault6.test @@ -253,7 +253,7 @@ do_faultsim_test 5.2 -faults oom* -prep { SELECT rowid, mit(matchinfo(t1, 'x')) FROM t1 WHERE t1 MATCH 'a AND c' } } -test { - faultsim_test_result [list 0 $::res] + faultsim_test_result [list 0 $::res] {1 {SQL logic error}} } do_faultsim_test 5.3 -faults oom* -prep { @@ -264,7 +264,7 @@ do_faultsim_test 5.3 -faults oom* -prep { SELECT count(*) FROM t1 WHERE t1 MATCH 'd AND e AND f' } } -test { - faultsim_test_result {0 29} + faultsim_test_result {0 29} {1 {SQL logic error}} } do_faultsim_test 5.4 -faults oom* -prep { @@ -275,7 +275,7 @@ do_faultsim_test 5.4 -faults oom* -prep { SELECT count(*) FROM t1 WHERE t1 MATCH 'x + e' } } -test { - faultsim_test_result {0 1} + faultsim_test_result {0 1} {1 {SQL logic error}} } #------------------------------------------------------------------------- diff --git a/ext/fts5/test/fts5fault9.test b/ext/fts5/test/fts5fault9.test index 1daa5c1cc9..669b13efe7 100644 --- a/ext/fts5/test/fts5fault9.test +++ b/ext/fts5/test/fts5fault9.test @@ -24,6 +24,8 @@ ifcapable !fts5 { foreach_detail_mode $testprefix { +if {"%DETAIL%" != "none"} continue + fts5_aux_test_functions db do_execsql_test 1.0 { @@ -98,14 +100,16 @@ do_faultsim_test 4.1 -faults oom-t* -body { execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('2') } } -test { faultsim_test_result \ - {0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} {1 SQLITE_NOMEM} + {0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} \ + {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}} } do_faultsim_test 4.2 -faults oom-t* -body { execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('a5 OR b5 OR c5') } } -test { faultsim_test_result \ - {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} {1 SQLITE_NOMEM} + {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} \ + {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}} } diff --git a/ext/fts5/test/fts5faultB.test b/ext/fts5/test/fts5faultB.test index a4fef523f5..2faec706d5 100644 --- a/ext/fts5/test/fts5faultB.test +++ b/ext/fts5/test/fts5faultB.test @@ -130,5 +130,22 @@ do_faultsim_test 4.2 -faults oom* -body { faultsim_test_result {0 {2 3}} } +#------------------------------------------------------------------------- +# Test OOM injection while parsing a CARET expression +# +reset_db +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a); + INSERT INTO t1 VALUES('a b c d'); -- 1 + INSERT INTO t1 VALUES('d a b c'); -- 2 + INSERT INTO t1 VALUES('c d a b'); -- 3 + INSERT INTO t1 VALUES('b c d a'); -- 4 +} +do_faultsim_test 5.1 -faults oom* -body { + execsql { SELECT rowid FROM t1('^a OR ^b') } +} -test { + faultsim_test_result {0 {1 4}} +} + finish_test diff --git a/ext/fts5/test/fts5first.test b/ext/fts5/test/fts5first.test new file mode 100644 index 0000000000..b2cac1fdf1 --- /dev/null +++ b/ext/fts5/test/fts5first.test @@ -0,0 +1,96 @@ +# 2017 November 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. +# +#*********************************************************************** + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5first + +ifcapable !fts5 { + finish_test + return +} + + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE x1 USING fts5(a, b); +} + +foreach {tn expr ok} { + 1 {^abc} 1 + 2 {^abc + def} 1 + 3 {^ "abc def"} 1 + 4 {^"abc def"} 1 + 5 {abc ^def} 1 + 6 {abc + ^def} 0 + 7 {abc ^+ def} 0 + 8 {"^abc"} 1 + 9 {NEAR(^abc def)} 0 +} { + set res(0) {/1 {fts5: syntax error near .*}/} + set res(1) {0 {}} + + do_catchsql_test 1.$tn { SELECT * FROM x1($expr) } $res($ok) +} + +#------------------------------------------------------------------------- +# +do_execsql_test 2.0 { + INSERT INTO x1 VALUES('a b c', 'b c a'); +} + +foreach {tn expr match} { + 1 {^a} 1 + 2 {^b} 1 + 3 {^c} 0 + 4 {^a + b} 1 + 5 {^b + c} 1 + 6 {^c + a} 0 + 7 {^"c a"} 0 + 8 {a:^a} 1 + 9 {a:^b} 0 + 10 {a:^"a b"} 1 +} { + do_execsql_test 2.$tn { SELECT EXISTS (SELECT rowid FROM x1($expr)) } $match +} + +#------------------------------------------------------------------------- +# +do_execsql_test 3.0 { + DELETE FROM x1; + INSERT INTO x1 VALUES('b a', 'c a'); + INSERT INTO x1 VALUES('a a', 'c c'); + INSERT INTO x1 VALUES('a b', 'a a'); +} +fts5_aux_test_functions db + +foreach {tn expr expect} { + 1 {^a} {{2 1}} + 2 {^c AND ^b} {{0 2} {1 0}} +} { + do_execsql_test 3.$tn { + SELECT fts5_test_queryphrase(x1) FROM x1($expr) LIMIT 1 + } [list $expect] +} + +#------------------------------------------------------------------------- +# +do_execsql_test 3.1 { + CREATE VIRTUAL TABLE x2 USING fts5(a, b, c, detail=column); +} + +do_catchsql_test 3.2 { + SELECT * FROM x2('a + b'); +} {1 {fts5: phrase queries are not supported (detail!=full)}} + +do_catchsql_test 3.3 { + SELECT * FROM x2('^a'); +} {1 {fts5: phrase queries are not supported (detail!=full)}} +finish_test + diff --git a/ext/fts5/test/fts5plan.test b/ext/fts5/test/fts5plan.test index a7b70f5b73..8f57e39a81 100644 --- a/ext/fts5/test/fts5plan.test +++ b/ext/fts5/test/fts5plan.test @@ -29,38 +29,37 @@ do_execsql_test 1.0 { do_eqp_test 1.1 { SELECT * FROM t1, f1 WHERE f1 MATCH t1.x } { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:} + QUERY PLAN + |--SCAN TABLE t1 + `--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537: } do_eqp_test 1.2 { SELECT * FROM t1, f1 WHERE f1 > t1.x } { - 0 0 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:} - 0 1 0 {SCAN TABLE t1} + QUERY PLAN + |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0: + `--SCAN TABLE t1 } do_eqp_test 1.3 { SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff } { - 0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537: + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 1.4 { SELECT * FROM f1 ORDER BY rank } { - 0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0: + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 1.5 { SELECT * FROM f1 WHERE rank MATCH ? -} { - 0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:} -} - - - +} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:} finish_test diff --git a/ext/fts5/test/fts5query.test b/ext/fts5/test/fts5query.test index 854651ef4f..5237e8e250 100644 --- a/ext/fts5/test/fts5query.test +++ b/ext/fts5/test/fts5query.test @@ -64,7 +64,7 @@ for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} { execsql COMMIT } {} - do_execsql_test 1.$tn.2 { + do_execsql_test 2.$tn.2 { INSERT INTO t1(t1) VALUES('integrity-check'); } @@ -77,5 +77,15 @@ for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} { } } +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE x1 USING fts5(a); + INSERT INTO x1(rowid, a) VALUES(-1000000000000, 'toyota'); + INSERT INTO x1(rowid, a) VALUES(1, 'tarago'); +} +do_execsql_test 3.1 { + SELECT rowid FROM x1('t*'); +} {-1000000000000 1} + finish_test diff --git a/ext/fts5/test/fts5rank.test b/ext/fts5/test/fts5rank.test index 1268eebe3c..0a986b5005 100644 --- a/ext/fts5/test/fts5rank.test +++ b/ext/fts5/test/fts5rank.test @@ -148,7 +148,19 @@ do_execsql_test 4.1 { VTest MATCH 'wrinkle in time OR a wrinkle in time' ORDER BY rank; } {{wrinkle in time} {Bill Smith}} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE ttt USING fts5(a); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO ttt SELECT 'word ' || i FROM s; +} - +do_execsql_test 5.1 { + SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank; +} {30 31 32 33 34 35 36 37 38 39 40} finish_test + diff --git a/ext/fts5/test/fts5unicode.test b/ext/fts5/test/fts5unicode.test index a9874ccfca..e2d0f60124 100644 --- a/ext/fts5/test/fts5unicode.test +++ b/ext/fts5/test/fts5unicode.test @@ -41,7 +41,6 @@ foreach {tn t} {1 ascii 2 unicode61} { #------------------------------------------------------------------------- # Check that "unicode61" really is the default tokenizer. # - do_execsql_test 2.0 " CREATE VIRTUAL TABLE t1 USING fts5(x); CREATE VIRTUAL TABLE t2 USING fts5(x, tokenize = unicode61); @@ -56,5 +55,31 @@ do_execsql_test 2.1 " SELECT 't3' FROM t3 WHERE t3 MATCH '\xE0\xE8\xEC'; " {t1 t2} +#------------------------------------------------------------------------- +# Check that codepoints that require 4 bytes to store in utf-8 (those that +# require 17 or more bits to store). +# + +set A [db one {SELECT char(0x1F75E)}] ;# Type So +set B [db one {SELECT char(0x1F5FD)}] ;# Type So +set C [db one {SELECT char(0x2F802)}] ;# Type Lo +set D [db one {SELECT char(0x2F808)}] ;# Type Lo + +do_execsql_test 3.0 " + CREATE VIRTUAL TABLE xyz USING fts5(x, + tokenize = \"unicode61 separators '$C' tokenchars '$A'\" + ); + CREATE VIRTUAL TABLE xyz_v USING fts5vocab(xyz, row); + + INSERT INTO xyz VALUES('$A$B$C$D'); +" + +do_execsql_test 3.1 { + SELECT * FROM xyz_v; +} [list $A 1 1 $D 1 1] + + + + finish_test diff --git a/ext/fts5/test/fts5unicode4.test b/ext/fts5/test/fts5unicode4.test new file mode 100644 index 0000000000..dfd7f5a254 --- /dev/null +++ b/ext/fts5/test/fts5unicode4.test @@ -0,0 +1,31 @@ +# 2018 July 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. +# +#*********************************************************************** +# +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5unicode4 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE sss USING fts5(a, prefix=3); +} + +do_execsql_test 1.1 { + INSERT INTO sss VALUES('まりや'); +} + +finish_test diff --git a/ext/fts5/test/fts5vocab2.test b/ext/fts5/test/fts5vocab2.test new file mode 100644 index 0000000000..4a0a1f4e3d --- /dev/null +++ b/ext/fts5/test/fts5vocab2.test @@ -0,0 +1,209 @@ +# 2017 August 10 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The tests in this file focus on testing the fts5vocab module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5vocab + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b); + CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance); + + INSERT INTO t1 VALUES('one two', 'two three'); + INSERT INTO t1 VALUES('three four', 'four five five five'); +} + +do_execsql_test 1.1 { + SELECT * FROM v1; +} { + five 2 b 1 + five 2 b 2 + five 2 b 3 + four 2 a 1 + four 2 b 0 + one 1 a 0 + three 1 b 1 + three 2 a 0 + two 1 a 1 + two 1 b 0 +} + +do_execsql_test 1.2 { + SELECT * FROM v1 WHERE term='three'; +} { + three 1 b 1 + three 2 a 0 +} + +do_execsql_test 1.3 { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + SELECT * FROM v1; + ROLLBACK; +} { + one 1 a 0 + three 1 b 1 + two 1 a 1 + two 1 b 0 +} + +do_execsql_test 1.4 { + BEGIN; + DELETE FROM t1 WHERE rowid=1; + SELECT * FROM v1; + ROLLBACK; +} { + five 2 b 1 + five 2 b 2 + five 2 b 3 + four 2 a 1 + four 2 b 0 + three 2 a 0 +} + +do_execsql_test 1.5 { + DELETE FROM t1; + SELECT * FROM v1; +} { +} + +#------------------------------------------------------------------------- +# +do_execsql_test 2.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS v1; + + CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=column); + CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance); + + INSERT INTO t1 VALUES('one two', 'two three'); + INSERT INTO t1 VALUES('three four', 'four five five five'); +} + +do_execsql_test 2.1 { + SELECT * FROM v1; +} { + five 2 b {} + four 2 a {} + four 2 b {} + one 1 a {} + three 1 b {} + three 2 a {} + two 1 a {} + two 1 b {} +} + +do_execsql_test 2.2 { + SELECT * FROM v1 WHERE term='three'; +} { + three 1 b {} + three 2 a {} +} + +do_execsql_test 2.3 { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + SELECT * FROM v1; + ROLLBACK; +} { + one 1 a {} + three 1 b {} + two 1 a {} + two 1 b {} +} + +do_execsql_test 2.4 { + BEGIN; + DELETE FROM t1 WHERE rowid=1; + SELECT * FROM v1; + ROLLBACK; +} { + five 2 b {} + four 2 a {} + four 2 b {} + three 2 a {} +} + +do_execsql_test 2.5 { + DELETE FROM t1; + SELECT * FROM v1; +} { +} + +#------------------------------------------------------------------------- +# +do_execsql_test 3.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS v1; + + CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=none); + CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance); + + INSERT INTO t1 VALUES('one two', 'two three'); + INSERT INTO t1 VALUES('three four', 'four five five five'); +} + +do_execsql_test 3.1 { + SELECT * FROM v1; +} { + five 2 {} {} + four 2 {} {} + one 1 {} {} + three 1 {} {} + three 2 {} {} + two 1 {} {} +} + +do_execsql_test 3.2 { + SELECT * FROM v1 WHERE term='three'; +} { + three 1 {} {} + three 2 {} {} +} + +do_execsql_test 3.3 { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + SELECT * FROM v1; + ROLLBACK; +} { + one 1 {} {} + three 1 {} {} + two 1 {} {} +} + +do_execsql_test 3.4 { + BEGIN; + DELETE FROM t1 WHERE rowid=1; + SELECT * FROM v1; + ROLLBACK; +} { + five 2 {} {} + four 2 {} {} + three 2 {} {} +} + +do_execsql_test 3.5 { + DELETE FROM t1; + SELECT * FROM v1; +} { +} + +finish_test + diff --git a/ext/icu/README.txt b/ext/icu/README.txt index d744f74981..af75d22e61 100644 --- a/ext/icu/README.txt +++ b/ext/icu/README.txt @@ -39,8 +39,8 @@ SQLite. Documentation follows. To utilise "general" case mapping, the upper() or lower() scalar functions are invoked with one argument: - upper('ABC') -> 'abc' - lower('abc') -> 'ABC' + upper('abc') -> 'ABC' + lower('ABC') -> 'abc' To access ICU "language specific" case mapping, upper() or lower() should be invoked with two arguments. The second argument is the name diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 7c37812d86..13524ebc2a 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -28,7 +28,9 @@ ** provide case-independent matching. */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) +#if !defined(SQLITE_CORE) \ + || defined(SQLITE_ENABLE_ICU) \ + || defined(SQLITE_ENABLE_ICU_COLLATIONS) /* Include ICU headers */ #include @@ -45,6 +47,26 @@ #include "sqlite3.h" #endif +/* +** This function is called when an ICU function called from within +** the implementation of an SQL scalar function returns an error. +** +** The scalar function context passed as the first argument is +** loaded with an error message based on the following two args. +*/ +static void icuFunctionError( + sqlite3_context *pCtx, /* SQLite scalar function context */ + const char *zName, /* Name of ICU function that failed */ + UErrorCode e /* Error code returned by ICU function */ +){ + char zBuf[128]; + sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); + zBuf[127] = '\0'; + sqlite3_result_error(pCtx, zBuf, -1); +} + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) + /* ** Maximum length (in bytes) of the pattern in a LIKE or GLOB ** operator. @@ -102,15 +124,15 @@ static int icuLikeCompare( const uint8_t *zString, /* The UTF-8 string to compare against */ const UChar32 uEsc /* The escape character */ ){ - static const int MATCH_ONE = (UChar32)'_'; - static const int MATCH_ALL = (UChar32)'%'; + static const uint32_t MATCH_ONE = (uint32_t)'_'; + static const uint32_t MATCH_ALL = (uint32_t)'%'; int prevEscape = 0; /* True if the previous character was uEsc */ while( 1 ){ /* Read (and consume) the next character from the input pattern. */ - UChar32 uPattern; + uint32_t uPattern; SQLITE_ICU_READ_UTF8(zPattern, uPattern); if( uPattern==0 ) break; @@ -152,16 +174,16 @@ static int icuLikeCompare( if( *zString==0 ) return 0; SQLITE_ICU_SKIP_UTF8(zString); - }else if( !prevEscape && uPattern==uEsc){ + }else if( !prevEscape && uPattern==(uint32_t)uEsc){ /* Case 3. */ prevEscape = 1; }else{ /* Case 4. */ - UChar32 uString; + uint32_t uString; SQLITE_ICU_READ_UTF8(zString, uString); - uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT); - uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT); + uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT); + uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT); if( uString!=uPattern ){ return 0; } @@ -224,24 +246,6 @@ static void icuLikeFunc( } } -/* -** This function is called when an ICU function called from within -** the implementation of an SQL scalar function returns an error. -** -** The scalar function context passed as the first argument is -** loaded with an error message based on the following two args. -*/ -static void icuFunctionError( - sqlite3_context *pCtx, /* SQLite scalar function context */ - const char *zName, /* Name of ICU function that failed */ - UErrorCode e /* Error code returned by ICU function */ -){ - char zBuf[128]; - sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); - zBuf[127] = '\0'; - sqlite3_result_error(pCtx, zBuf, -1); -} - /* ** Function to delete compiled regexp objects. Registered as ** a destructor function with sqlite3_set_auxdata(). @@ -407,6 +411,8 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ assert( 0 ); /* Unreachable */ } +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ + /* ** Collation sequence destructor function. The pCtx argument points to ** a UCollator structure previously allocated using ucol_open(). @@ -501,6 +507,7 @@ int sqlite3IcuInit(sqlite3 *db){ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { {"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation}, +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc}, {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, @@ -512,10 +519,10 @@ int sqlite3IcuInit(sqlite3 *db){ {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ }; int rc = SQLITE_OK; int i; - for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ const struct IcuScalar *p = &scalars[i]; diff --git a/ext/lsm1/Makefile b/ext/lsm1/Makefile index a4f8ebd367..7022b5682c 100644 --- a/ext/lsm1/Makefile +++ b/ext/lsm1/Makefile @@ -43,7 +43,7 @@ LSMTESTSRC = $(LSMDIR)/lsm-test/lsmtest1.c $(LSMDIR)/lsm-test/lsmtest2.c \ # all: lsm.so -LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) +LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB lsm.so: $(LSMOBJ) $(TCCX) -shared -o lsm.so $(LSMOBJ) @@ -53,4 +53,4 @@ lsm.so: $(LSMOBJ) lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o # $(TCPPX) -c $(TOP)/lsm-test/lsmtest_tdb2.cc - $(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) + $(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) -lz diff --git a/ext/lsm1/lsm-test/lsmtest.h b/ext/lsm1/lsm-test/lsmtest.h index 249bc999e0..ca60424add 100644 --- a/ext/lsm1/lsm-test/lsmtest.h +++ b/ext/lsm1/lsm-test/lsmtest.h @@ -121,6 +121,7 @@ int test_mdb_scan(TestDb *, void *, int, void *, int, void *, int, */ int test_lsm_open(const char*, const char *zFile, int bClear, TestDb **ppDb); int test_lsm_lomem_open(const char*, const char*, int bClear, TestDb **ppDb); +int test_lsm_lomem2_open(const char*, const char*, int bClear, TestDb **ppDb); int test_lsm_zip_open(const char*, const char*, int bClear, TestDb **ppDb); int test_lsm_small_open(const char*, const char*, int bClear, TestDb **ppDb); int test_lsm_mt2(const char*, const char *zFile, int bClear, TestDb **ppDb); diff --git a/ext/lsm1/lsm-test/lsmtest1.c b/ext/lsm1/lsm-test/lsmtest1.c index 665dc15e58..dcbc718424 100644 --- a/ext/lsm1/lsm-test/lsmtest1.c +++ b/ext/lsm1/lsm-test/lsmtest1.c @@ -274,6 +274,7 @@ static void doDataTest1( int rc = LSM_OK; Datasource *pData; TestDb *pDb; + int iToggle = 0; /* Start the test case, open a database and allocate the datasource. */ pDb = testOpen(zSystem, 1, &rc); @@ -287,8 +288,11 @@ static void doDataTest1( testWriteDatasourceRange(pDb, pData, i, p->nVerify, &rc); i += p->nVerify; + if( iToggle ) testBegin(pDb, 1, &rc); /* Check that the db content is correct. */ testDbContents(pDb, pData, p->nRow, 0, i-1, p->nTest, p->bTestScan, &rc); + if( iToggle ) testCommit(pDb, 0, &rc); + iToggle = (iToggle+1)%2; if( bRecover ){ testReopenRecover(&pDb, &rc); diff --git a/ext/lsm1/lsm-test/lsmtest_tdb.c b/ext/lsm1/lsm-test/lsmtest_tdb.c index 8377bc2ed2..9c4f9df8a4 100644 --- a/ext/lsm1/lsm-test/lsmtest_tdb.c +++ b/ext/lsm1/lsm-test/lsmtest_tdb.c @@ -721,6 +721,7 @@ static struct Lib { { "sqlite3", "testdb.sqlite", sql_open }, { "lsm_small", "testdb.lsm_small", test_lsm_small_open }, { "lsm_lomem", "testdb.lsm_lomem", test_lsm_lomem_open }, + { "lsm_lomem2", "testdb.lsm_lomem2", test_lsm_lomem2_open }, #ifdef HAVE_ZLIB { "lsm_zip", "testdb.lsm_zip", test_lsm_zip_open }, #endif diff --git a/ext/lsm1/lsm-test/lsmtest_tdb3.c b/ext/lsm1/lsm-test/lsmtest_tdb3.c index 1862023bad..e29497af20 100644 --- a/ext/lsm1/lsm-test/lsmtest_tdb3.c +++ b/ext/lsm1/lsm-test/lsmtest_tdb3.c @@ -617,8 +617,12 @@ static int test_lsm_fetch( if( pKey==0 ) return LSM_OK; - rc = lsm_csr_open(pDb->db, &csr); - if( rc!=LSM_OK ) return rc; + if( pDb->pCsr==0 ){ + rc = lsm_csr_open(pDb->db, &csr); + if( rc!=LSM_OK ) return rc; + }else{ + csr = pDb->pCsr; + } rc = lsm_csr_seek(csr, pKey, nKey, LSM_SEEK_EQ); if( rc==LSM_OK ){ @@ -638,7 +642,9 @@ static int test_lsm_fetch( *pnVal = -1; } } - lsm_csr_close(csr); + if( pDb->pCsr==0 ){ + lsm_csr_close(csr); + } return rc; } @@ -652,10 +658,28 @@ static int test_lsm_scan( ){ LsmDb *pDb = (LsmDb *)pTestDb; lsm_cursor *csr; + lsm_cursor *csr2 = 0; int rc; - rc = lsm_csr_open(pDb->db, &csr); - if( rc!=LSM_OK ) return rc; + if( pDb->pCsr==0 ){ + rc = lsm_csr_open(pDb->db, &csr); + if( rc!=LSM_OK ) return rc; + }else{ + rc = LSM_OK; + csr = pDb->pCsr; + } + + /* To enhance testing, if both pLast and pFirst are defined, seek the + ** cursor to the "end" boundary here. Then the next block seeks it to + ** the "start" ready for the scan. The point is to test that cursors + ** can be reused. */ + if( pLast && pFirst ){ + if( bReverse ){ + rc = lsm_csr_seek(csr, pFirst, nFirst, LSM_SEEK_LE); + }else{ + rc = lsm_csr_seek(csr, pLast, nLast, LSM_SEEK_GE); + } + } if( bReverse ){ if( pLast ){ @@ -696,7 +720,9 @@ static int test_lsm_scan( } } - lsm_csr_close(csr); + if( pDb->pCsr==0 ){ + lsm_csr_close(csr); + } return rc; } @@ -762,6 +788,7 @@ static void xWorkHook(lsm_db *db, void *pArg){ #define TEST_MT_MIN_CKPT -4 #define TEST_MT_MAX_CKPT -5 + int test_lsm_config_str( LsmDb *pLsm, lsm_db *db, @@ -1033,6 +1060,19 @@ int test_lsm_lomem_open( return testLsmOpen(zCfg, zFilename, bClear, ppDb); } +int test_lsm_lomem2_open( + const char *zSpec, + const char *zFilename, + int bClear, + TestDb **ppDb +){ + /* "max_freelist=4 autocheckpoint=32" */ + const char *zCfg = + "page_size=512 block_size=64 autoflush=0 mmap=0 " + ; + return testLsmOpen(zCfg, zFilename, bClear, ppDb); +} + int test_lsm_zip_open( const char *zSpec, const char *zFilename, diff --git a/ext/lsm1/lsmInt.h b/ext/lsm1/lsmInt.h index b346d8dded..0f822e4793 100644 --- a/ext/lsm1/lsmInt.h +++ b/ext/lsm1/lsmInt.h @@ -110,7 +110,7 @@ typedef unsigned long long int u64; #endif /* A page number is a 64-bit integer. */ -typedef i64 Pgno; +typedef i64 LsmPgno; #ifdef LSM_DEBUG int lsmErrorBkpt(int); @@ -402,9 +402,9 @@ struct lsm_db { }; struct Segment { - Pgno iFirst; /* First page of this run */ - Pgno iLastPg; /* Last page of this run */ - Pgno iRoot; /* Root page number (if any) */ + LsmPgno iFirst; /* First page of this run */ + LsmPgno iLastPg; /* Last page of this run */ + LsmPgno iRoot; /* Root page number (if any) */ int nSize; /* Size of this run in pages */ Redirect *pRedirect; /* Block redirects (or NULL) */ @@ -456,7 +456,7 @@ struct Level { ** output segment. */ struct MergeInput { - Pgno iPg; /* Page on which next input is stored */ + LsmPgno iPg; /* Page on which next input is stored */ int iCell; /* Cell containing next input to merge */ }; struct Merge { @@ -465,7 +465,7 @@ struct Merge { MergeInput splitkey; /* Location in file of current splitkey */ int nSkip; /* Number of separators entries to skip */ int iOutputOff; /* Write offset on output page */ - Pgno iCurrentPtr; /* Current pointer value */ + LsmPgno iCurrentPtr; /* Current pointer value */ }; /* @@ -579,10 +579,10 @@ struct Snapshot { Redirect redirect; /* Block redirection array */ /* Used by worker snapshots only */ - int nBlock; /* Number of blocks in database file */ - Pgno aiAppend[LSM_APPLIST_SZ]; /* Append point list */ - Freelist freelist; /* Free block list */ - u32 nWrite; /* Total number of pages written to disk */ + int nBlock; /* Number of blocks in database file */ + LsmPgno aiAppend[LSM_APPLIST_SZ]; /* Append point list */ + Freelist freelist; /* Free block list */ + u32 nWrite; /* Total number of pages written to disk */ }; #define LSM_INITIAL_SNAPSHOT_ID 11 @@ -710,7 +710,7 @@ void lsmFsSetPageSize(FileSystem *, int); int lsmFsFileid(lsm_db *pDb, void **ppId, int *pnId); /* Creating, populating, gobbling and deleting sorted runs. */ -void lsmFsGobble(lsm_db *, Segment *, Pgno *, int); +void lsmFsGobble(lsm_db *, Segment *, LsmPgno *, int); int lsmFsSortedDelete(FileSystem *, Snapshot *, int, Segment *); int lsmFsSortedFinish(FileSystem *, Segment *); int lsmFsSortedAppend(FileSystem *, Snapshot *, Level *, int, Page **); @@ -727,14 +727,14 @@ void lsmSortedSplitkey(lsm_db *, Level *, int *); /* Reading sorted run content. */ int lsmFsDbPageLast(FileSystem *pFS, Segment *pSeg, Page **ppPg); -int lsmFsDbPageGet(FileSystem *, Segment *, Pgno, Page **); +int lsmFsDbPageGet(FileSystem *, Segment *, LsmPgno, Page **); int lsmFsDbPageNext(Segment *, Page *, int eDir, Page **); u8 *lsmFsPageData(Page *, int *); int lsmFsPageRelease(Page *); int lsmFsPagePersist(Page *); void lsmFsPageRef(Page *); -Pgno lsmFsPageNumber(Page *); +LsmPgno lsmFsPageNumber(Page *); int lsmFsNRead(FileSystem *); int lsmFsNWrite(FileSystem *); @@ -748,7 +748,7 @@ int lsmFsDbPageIsLast(Segment *pSeg, Page *pPg); int lsmFsIntegrityCheck(lsm_db *); #endif -Pgno lsmFsRedirectPage(FileSystem *, Redirect *, Pgno); +LsmPgno lsmFsRedirectPage(FileSystem *, Redirect *, LsmPgno); int lsmFsPageWritable(Page *); @@ -768,8 +768,8 @@ int lsmFsSyncDb(FileSystem *, int); void lsmFsFlushWaiting(FileSystem *, int *); /* Used by lsm_info(ARRAY_STRUCTURE) and lsm_config(MMAP) */ -int lsmInfoArrayStructure(lsm_db *pDb, int bBlock, Pgno iFirst, char **pzOut); -int lsmInfoArrayPages(lsm_db *pDb, Pgno iFirst, char **pzOut); +int lsmInfoArrayStructure(lsm_db *pDb, int bBlock, LsmPgno iFirst, char **pz); +int lsmInfoArrayPages(lsm_db *pDb, LsmPgno iFirst, char **pzOut); int lsmConfigMmap(lsm_db *pDb, int *piParam); int lsmEnvOpen(lsm_env *, const char *, int, lsm_file **); @@ -785,7 +785,7 @@ void lsmEnvSleep(lsm_env *, int); int lsmFsReadSyncedId(lsm_db *db, int, i64 *piVal); -int lsmFsSegmentContainsPg(FileSystem *pFS, Segment *, Pgno, int *); +int lsmFsSegmentContainsPg(FileSystem *pFS, Segment *, LsmPgno, int *); void lsmFsPurgeCache(FileSystem *); @@ -796,7 +796,7 @@ void lsmFsPurgeCache(FileSystem *); /* ** Functions from file "lsm_sorted.c". */ -int lsmInfoPageDump(lsm_db *, Pgno, int, char **); +int lsmInfoPageDump(lsm_db *, LsmPgno, int, char **); void lsmSortedCleanup(lsm_db *); int lsmSortedAutoWork(lsm_db *, int nUnit); diff --git a/ext/lsm1/lsm_ckpt.c b/ext/lsm1/lsm_ckpt.c index cf4c55bf84..ba92a823cf 100644 --- a/ext/lsm1/lsm_ckpt.c +++ b/ext/lsm1/lsm_ckpt.c @@ -389,7 +389,7 @@ static void ckptExportAppendlist( int *pRc /* IN/OUT: Error code */ ){ int i; - Pgno *aiAppend = db->pWorker->aiAppend; + LsmPgno *aiAppend = db->pWorker->aiAppend; for(i=0; inPagesize <= pFS->nMapLimit); } @@ -540,7 +540,7 @@ static int fsMmapPage(FileSystem *pFS, Pgno iReal){ ** Given that there are currently nHash slots in the hash table, return ** the hash key for file iFile, page iPg. */ -static int fsHashKey(int nHash, Pgno iPg){ +static int fsHashKey(int nHash, LsmPgno iPg){ return (iPg % nHash); } @@ -880,13 +880,13 @@ void lsmFsSetBlockSize(FileSystem *pFS, int nBlocksize){ ** page on each block is the byte offset immediately following the 4-byte ** "previous block" pointer at the start of each block. */ -static Pgno fsFirstPageOnBlock(FileSystem *pFS, int iBlock){ - Pgno iPg; +static LsmPgno fsFirstPageOnBlock(FileSystem *pFS, int iBlock){ + LsmPgno iPg; if( pFS->pCompress ){ if( iBlock==1 ){ iPg = pFS->nMetasize * 2 + 4; }else{ - iPg = pFS->nBlocksize * (Pgno)(iBlock-1) + 4; + iPg = pFS->nBlocksize * (LsmPgno)(iBlock-1) + 4; } }else{ const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize); @@ -907,9 +907,9 @@ static Pgno fsFirstPageOnBlock(FileSystem *pFS, int iBlock){ ** page on each block is the byte offset of the byte immediately before ** the 4-byte "next block" pointer at the end of each block. */ -static Pgno fsLastPageOnBlock(FileSystem *pFS, int iBlock){ +static LsmPgno fsLastPageOnBlock(FileSystem *pFS, int iBlock){ if( pFS->pCompress ){ - return pFS->nBlocksize * (Pgno)iBlock - 1 - 4; + return pFS->nBlocksize * (LsmPgno)iBlock - 1 - 4; }else{ const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize); return iBlock * nPagePerBlock; @@ -920,7 +920,7 @@ static Pgno fsLastPageOnBlock(FileSystem *pFS, int iBlock){ ** Return the block number of the block that page iPg is located on. ** Blocks are numbered starting from 1. */ -static int fsPageToBlock(FileSystem *pFS, Pgno iPg){ +static int fsPageToBlock(FileSystem *pFS, LsmPgno iPg){ if( pFS->pCompress ){ return (int)((iPg / pFS->nBlocksize) + 1); }else{ @@ -933,7 +933,7 @@ static int fsPageToBlock(FileSystem *pFS, Pgno iPg){ ** ** This function is only called in non-compressed database mode. */ -static int fsIsLast(FileSystem *pFS, Pgno iPg){ +static int fsIsLast(FileSystem *pFS, LsmPgno iPg){ const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize); assert( !pFS->pCompress ); return ( iPg && (iPg % nPagePerBlock)==0 ); @@ -944,7 +944,7 @@ static int fsIsLast(FileSystem *pFS, Pgno iPg){ ** ** This function is only called in non-compressed database mode. */ -static int fsIsFirst(FileSystem *pFS, Pgno iPg){ +static int fsIsFirst(FileSystem *pFS, LsmPgno iPg){ const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize); assert( !pFS->pCompress ); return ( (iPg % nPagePerBlock)==1 @@ -967,7 +967,7 @@ u8 *lsmFsPageData(Page *pPage, int *pnData){ /* ** Return the page number of a page. */ -Pgno lsmFsPageNumber(Page *pPage){ +LsmPgno lsmFsPageNumber(Page *pPage){ /* assert( (pPage->flags & PAGE_DIRTY)==0 ); */ return pPage ? pPage->iPg : 0; } @@ -1058,7 +1058,7 @@ void lsmFsPurgeCache(FileSystem *pFS){ ** Either way, if argument piHash is not NULL set *piHash to the hash slot ** number that page iPg would be stored in before returning. */ -static Page *fsPageFindInHash(FileSystem *pFS, Pgno iPg, int *piHash){ +static Page *fsPageFindInHash(FileSystem *pFS, LsmPgno iPg, int *piHash){ Page *p; /* Return value */ int iHash = fsHashKey(pFS->nHash, iPg); @@ -1189,8 +1189,8 @@ static int fsRedirectBlock(Redirect *p, int iBlk){ ** object passed as the second argument, return the destination page to ** which it is redirected. Otherwise, return a copy of iPg. */ -Pgno lsmFsRedirectPage(FileSystem *pFS, Redirect *pRedir, Pgno iPg){ - Pgno iReal = iPg; +LsmPgno lsmFsRedirectPage(FileSystem *pFS, Redirect *pRedir, LsmPgno iPg){ + LsmPgno iReal = iPg; if( pRedir ){ const int nPagePerBlock = ( @@ -1203,7 +1203,7 @@ Pgno lsmFsRedirectPage(FileSystem *pFS, Redirect *pRedir, Pgno iPg){ if( iFrom>iBlk ) break; if( iFrom==iBlk ){ int iTo = pRedir->a[i].iTo; - iReal = iPg - (Pgno)(iFrom - iTo) * nPagePerBlock; + iReal = iPg - (LsmPgno)(iFrom - iTo) * nPagePerBlock; if( iTo==1 ){ iReal += (fsFirstPageOnBlock(pFS, 1)-1); } @@ -1217,7 +1217,7 @@ Pgno lsmFsRedirectPage(FileSystem *pFS, Redirect *pRedir, Pgno iPg){ } /* Required by the circular fsBlockNext<->fsPageGet dependency. */ -static int fsPageGet(FileSystem *, Segment *, Pgno, int, Page **, int *); +static int fsPageGet(FileSystem *, Segment *, LsmPgno, int, Page **, int *); /* ** Parameter iBlock is a database file block. This function reads the value @@ -1269,7 +1269,7 @@ static int fsBlockNext( /* ** Return the page number of the last page on the same block as page iPg. */ -Pgno fsLastPageOnPagesBlock(FileSystem *pFS, Pgno iPg){ +LsmPgno fsLastPageOnPagesBlock(FileSystem *pFS, LsmPgno iPg){ return fsLastPageOnBlock(pFS, fsPageToBlock(pFS, iPg)); } @@ -1537,7 +1537,7 @@ static int fsReadPagedata( static int fsPageGet( FileSystem *pFS, /* File-system handle */ Segment *pSeg, /* Block redirection to use (or NULL) */ - Pgno iPg, /* Page id */ + LsmPgno iPg, /* Page id */ int noContent, /* True to not load content from disk */ Page **ppPg, /* OUT: New page handle */ int *pnSpace /* OUT: Bytes of free space */ @@ -1549,7 +1549,7 @@ static int fsPageGet( /* In most cases iReal is the same as iPg. Except, if pSeg->pRedirect is ** not NULL, and the block containing iPg has been redirected, then iReal ** is the page number after redirection. */ - Pgno iReal = lsmFsRedirectPage(pFS, (pSeg ? pSeg->pRedirect : 0), iPg); + LsmPgno iReal = lsmFsRedirectPage(pFS, (pSeg ? pSeg->pRedirect : 0), iPg); assert_lists_are_ok(pFS); assert( iPg>=fsFirstPageOnBlock(pFS, 1) ); @@ -1689,8 +1689,8 @@ int lsmFsReadSyncedId(lsm_db *db, int iMeta, i64 *piVal){ static int fsRunEndsBetween( Segment *pRun, Segment *pIgnore, - Pgno iFirst, - Pgno iLast + LsmPgno iFirst, + LsmPgno iLast ){ return (pRun!=pIgnore && ( (pRun->iFirst>=iFirst && pRun->iFirst<=iLast) @@ -1705,8 +1705,8 @@ static int fsRunEndsBetween( static int fsLevelEndsBetween( Level *pLevel, Segment *pIgnore, - Pgno iFirst, - Pgno iLast + LsmPgno iFirst, + LsmPgno iLast ){ int i; @@ -1733,13 +1733,13 @@ static int fsFreeBlock( int iBlk /* Block number of block to free */ ){ int rc = LSM_OK; /* Return code */ - Pgno iFirst; /* First page on block iBlk */ - Pgno iLast; /* Last page on block iBlk */ + LsmPgno iFirst; /* First page on block iBlk */ + LsmPgno iLast; /* Last page on block iBlk */ Level *pLevel; /* Used to iterate through levels */ int iIn; /* Used to iterate through append points */ int iOut = 0; /* Used to output append points */ - Pgno *aApp = pSnapshot->aiAppend; + LsmPgno *aApp = pSnapshot->aiAppend; iFirst = fsFirstPageOnBlock(pFS, iBlk); iLast = fsLastPageOnBlock(pFS, iBlk); @@ -1811,11 +1811,16 @@ int lsmFsSortedDelete( ** number from the array that falls on block iBlk. Or, if none of the pages ** in aPgno[] fall on block iBlk, return 0. */ -static Pgno firstOnBlock(FileSystem *pFS, int iBlk, Pgno *aPgno, int nPgno){ - Pgno iRet = 0; +static LsmPgno firstOnBlock( + FileSystem *pFS, + int iBlk, + LsmPgno *aPgno, + int nPgno +){ + LsmPgno iRet = 0; int i; for(i=0; ipRedirect, iPg)); } @@ -1854,7 +1859,7 @@ static int fsSegmentRedirects(FileSystem *pFS, Segment *p){ void lsmFsGobble( lsm_db *pDb, Segment *pRun, - Pgno *aPgno, + LsmPgno *aPgno, int nPgno ){ int rc = LSM_OK; @@ -1871,7 +1876,7 @@ void lsmFsGobble( while( rc==LSM_OK ){ int iNext = 0; - Pgno iFirst = firstOnBlock(pFS, iBlk, aPgno, nPgno); + LsmPgno iFirst = firstOnBlock(pFS, iBlk, aPgno, nPgno); if( iFirst ){ pRun->iFirst = iFirst; break; @@ -1905,11 +1910,11 @@ void lsmFsGobble( static int fsNextPageOffset( FileSystem *pFS, /* File system object */ Segment *pSeg, /* Segment to move within */ - Pgno iPg, /* Offset of current page */ + LsmPgno iPg, /* Offset of current page */ int nByte, /* Size of current page including headers */ - Pgno *piNext /* OUT: Offset of next page. Or zero (EOF) */ + LsmPgno *piNext /* OUT: Offset of next page. Or zero (EOF) */ ){ - Pgno iNext; + LsmPgno iNext; int rc; assert( pFS->pCompress ); @@ -1939,8 +1944,8 @@ static int fsNextPageOffset( static int fsGetPageBefore( FileSystem *pFS, Segment *pSeg, - Pgno iPg, - Pgno *piPrev + LsmPgno iPg, + LsmPgno *piPrev ){ u8 aSz[3]; int rc; @@ -1990,7 +1995,7 @@ static int fsGetPageBefore( int lsmFsDbPageNext(Segment *pRun, Page *pPg, int eDir, Page **ppNext){ int rc = LSM_OK; FileSystem *pFS = pPg->pFS; - Pgno iPg = pPg->iPg; + LsmPgno iPg = pPg->iPg; assert( 0==fsSegmentRedirects(pFS, pRun) ); if( pFS->pCompress ){ @@ -2062,10 +2067,10 @@ int lsmFsDbPageNext(Segment *pRun, Page *pPg, int eDir, Page **ppNext){ ** start the new segment immediately following any segment that is part ** of the right-hand-side of pLvl. */ -static Pgno findAppendPoint(FileSystem *pFS, Level *pLvl){ +static LsmPgno findAppendPoint(FileSystem *pFS, Level *pLvl){ int i; - Pgno *aiAppend = pFS->pDb->pWorker->aiAppend; - Pgno iRet = 0; + LsmPgno *aiAppend = pFS->pDb->pWorker->aiAppend; + LsmPgno iRet = 0; for(i=LSM_APPLIST_SZ-1; iRet==0 && i>=0; i--){ if( (iRet = aiAppend[i]) ){ @@ -2098,10 +2103,10 @@ int lsmFsSortedAppend( ){ int rc = LSM_OK; Page *pPg = 0; - Pgno iApp = 0; - Pgno iNext = 0; + LsmPgno iApp = 0; + LsmPgno iNext = 0; Segment *p = &pLvl->lhs; - Pgno iPrev = p->iLastPg; + LsmPgno iPrev = p->iLastPg; *ppOut = 0; assert( p->pRedirect==0 ); @@ -2195,7 +2200,7 @@ int lsmFsSortedFinish(FileSystem *pFS, Segment *p){ */ if( fsLastPageOnPagesBlock(pFS, p->iLastPg)!=p->iLastPg ){ int i; - Pgno *aiAppend = pFS->pDb->pWorker->aiAppend; + LsmPgno *aiAppend = pFS->pDb->pWorker->aiAppend; for(i=0; iiLastPg+1; @@ -2226,7 +2231,7 @@ int lsmFsSortedFinish(FileSystem *pFS, Segment *p){ ** ** Return LSM_OK if successful, or an lsm error code if an error occurs. */ -int lsmFsDbPageGet(FileSystem *pFS, Segment *pSeg, Pgno iPg, Page **ppPg){ +int lsmFsDbPageGet(FileSystem *pFS, Segment *pSeg, LsmPgno iPg, Page **ppPg){ return fsPageGet(pFS, pSeg, iPg, 0, ppPg, 0); } @@ -2238,7 +2243,7 @@ int lsmFsDbPageGet(FileSystem *pFS, Segment *pSeg, Pgno iPg, Page **ppPg){ */ int lsmFsDbPageLast(FileSystem *pFS, Segment *pSeg, Page **ppPg){ int rc; - Pgno iPg = pSeg->iLastPg; + LsmPgno iPg = pSeg->iLastPg; if( pFS->pCompress ){ int nSpace; iPg++; @@ -2366,14 +2371,14 @@ static void fsMovePage( FileSystem *pFS, /* File system object */ int iTo, /* Destination block */ int iFrom, /* Source block */ - Pgno *piPg /* IN/OUT: Page number */ + LsmPgno *piPg /* IN/OUT: Page number */ ){ - Pgno iPg = *piPg; + LsmPgno iPg = *piPg; if( iFrom==fsPageToBlock(pFS, iPg) ){ const int nPagePerBlock = ( pFS->pCompress ? pFS ->nBlocksize : (pFS->nBlocksize / pFS->nPagesize) ); - *piPg = iPg - (Pgno)(iFrom - iTo) * nPagePerBlock; + *piPg = iPg - (LsmPgno)(iFrom - iTo) * nPagePerBlock; } } @@ -2457,21 +2462,21 @@ int lsmFsMoveBlock(FileSystem *pFS, Segment *pSeg, int iTo, int iFrom){ ** ** This function is only used in compressed database mode. */ -static Pgno fsAppendData( +static LsmPgno fsAppendData( FileSystem *pFS, /* File-system handle */ Segment *pSeg, /* Segment to append to */ const u8 *aData, /* Buffer containing data to write */ int nData, /* Size of buffer aData[] in bytes */ int *pRc /* IN/OUT: Error code */ ){ - Pgno iRet = 0; + LsmPgno iRet = 0; int rc = *pRc; assert( pFS->pCompress ); if( rc==LSM_OK ){ int nRem = 0; int nWrite = 0; - Pgno iLastOnBlock; - Pgno iApp = pSeg->iLastPg+1; + LsmPgno iLastOnBlock; + LsmPgno iApp = pSeg->iLastPg+1; /* If this is the first data written into the segment, find an append-point ** or allocate a new block. */ @@ -2519,7 +2524,7 @@ static Pgno fsAppendData( /* Set the "prev" pointer on the new block */ if( rc==LSM_OK ){ - Pgno iWrite; + LsmPgno iWrite; lsmPutU32(aPtr, fsPageToBlock(pFS, iApp)); iWrite = fsFirstPageOnBlock(pFS, iBlk); rc = lsmEnvWrite(pFS->pEnv, pFS->fdDb, iWrite-4, aPtr, sizeof(aPtr)); @@ -2588,11 +2593,11 @@ static int fsCompressIntoBuffer(FileSystem *pFS, Page *pPg){ static int fsAppendPage( FileSystem *pFS, Segment *pSeg, - Pgno *piNew, + LsmPgno *piNew, int *piPrev, int *piNext ){ - Pgno iPrev = pSeg->iLastPg; + LsmPgno iPrev = pSeg->iLastPg; int rc; assert( iPrev!=0 ); @@ -2650,7 +2655,7 @@ void lsmFsFlushWaiting(FileSystem *pFS, int *pRc){ /* ** If there exists a hash-table entry associated with page iPg, remove it. */ -static void fsRemoveHashEntry(FileSystem *pFS, Pgno iPg){ +static void fsRemoveHashEntry(FileSystem *pFS, LsmPgno iPg){ Page *p; int iHash = fsHashKey(pFS->nHash, iPg); @@ -2803,9 +2808,9 @@ int lsmFsSortedPadding( Segment *pSeg ){ int rc = LSM_OK; - if( pFS->pCompress ){ - Pgno iLast2; - Pgno iLast = pSeg->iLastPg; /* Current last page of segment */ + if( pFS->pCompress && pSeg->iFirst ){ + LsmPgno iLast2; + LsmPgno iLast = pSeg->iLastPg; /* Current last page of segment */ int nPad; /* Bytes of padding required */ u8 aSz[3]; @@ -2935,7 +2940,7 @@ int lsmFsSectorSize(FileSystem *pFS){ /* ** Helper function for lsmInfoArrayStructure(). */ -static Segment *startsWith(Segment *pRun, Pgno iFirst){ +static Segment *startsWith(Segment *pRun, LsmPgno iFirst){ return (iFirst==pRun->iFirst) ? pRun : 0; } @@ -2943,7 +2948,7 @@ static Segment *startsWith(Segment *pRun, Pgno iFirst){ ** Return the segment that starts with page iFirst, if any. If no such segment ** can be found, return NULL. */ -static Segment *findSegment(Snapshot *pWorker, Pgno iFirst){ +static Segment *findSegment(Snapshot *pWorker, LsmPgno iFirst){ Level *pLvl; /* Used to iterate through db levels */ Segment *pSeg = 0; /* Pointer to segment to return */ @@ -2970,7 +2975,7 @@ static Segment *findSegment(Snapshot *pWorker, Pgno iFirst){ int lsmInfoArrayStructure( lsm_db *pDb, int bBlock, /* True for block numbers only */ - Pgno iFirst, + LsmPgno iFirst, char **pzOut ){ int rc = LSM_OK; @@ -3035,7 +3040,7 @@ int lsmInfoArrayStructure( int lsmFsSegmentContainsPg( FileSystem *pFS, Segment *pSeg, - Pgno iPg, + LsmPgno iPg, int *pbRes ){ Redirect *pRedir = pSeg->pRedirect; @@ -3064,7 +3069,7 @@ int lsmFsSegmentContainsPg( ** ** If an error occurs, *pzOut is set to NULL and an LSM error code returned. */ -int lsmInfoArrayPages(lsm_db *pDb, Pgno iFirst, char **pzOut){ +int lsmInfoArrayPages(lsm_db *pDb, LsmPgno iFirst, char **pzOut){ int rc = LSM_OK; Snapshot *pWorker; /* Worker snapshot */ Segment *pSeg = 0; /* Array to report on */ @@ -3297,7 +3302,7 @@ int lsmFsIntegrityCheck(lsm_db *pDb){ */ int lsmFsDbPageIsLast(Segment *pSeg, Page *pPg){ if( pPg->pFS->pCompress ){ - Pgno iNext = 0; + LsmPgno iNext = 0; int rc; rc = fsNextPageOffset(pPg->pFS, pSeg, pPg->iPg, pPg->nCompress+6, &iNext); return (rc!=LSM_OK || iNext==0); diff --git a/ext/lsm1/lsm_main.c b/ext/lsm1/lsm_main.c index 8a324a3efe..a9c48e004e 100644 --- a/ext/lsm1/lsm_main.c +++ b/ext/lsm1/lsm_main.c @@ -583,14 +583,14 @@ int lsm_info(lsm_db *pDb, int eParam, ...){ } case LSM_INFO_ARRAY_STRUCTURE: { - Pgno pgno = va_arg(ap, Pgno); + LsmPgno pgno = va_arg(ap, LsmPgno); char **pzVal = va_arg(ap, char **); rc = lsmInfoArrayStructure(pDb, 0, pgno, pzVal); break; } case LSM_INFO_ARRAY_PAGES: { - Pgno pgno = va_arg(ap, Pgno); + LsmPgno pgno = va_arg(ap, LsmPgno); char **pzVal = va_arg(ap, char **); rc = lsmInfoArrayPages(pDb, pgno, pzVal); break; @@ -598,7 +598,7 @@ int lsm_info(lsm_db *pDb, int eParam, ...){ case LSM_INFO_PAGE_HEX_DUMP: case LSM_INFO_PAGE_ASCII_DUMP: { - Pgno pgno = va_arg(ap, Pgno); + LsmPgno pgno = va_arg(ap, LsmPgno); char **pzVal = va_arg(ap, char **); int bUnlock = 0; rc = infoGetWorker(pDb, 0, &bUnlock); @@ -683,7 +683,7 @@ static int doWriteOp( int nDiff; if( nQuant>pDb->nTreeLimit ){ - nQuant = pDb->nTreeLimit; + nQuant = LSM_MAX(pDb->nTreeLimit, pgsz); } nBefore = lsmTreeSize(pDb); diff --git a/ext/lsm1/lsm_shared.c b/ext/lsm1/lsm_shared.c index 83e44b4705..2fdacf1eca 100644 --- a/ext/lsm1/lsm_shared.c +++ b/ext/lsm1/lsm_shared.c @@ -340,9 +340,6 @@ static int doDbConnect(lsm_db *pDb){ /* Obtain a pointer to the shared-memory header */ assert( pDb->pShmhdr==0 ); assert( pDb->bReadonly==0 ); - rc = lsmShmCacheChunks(pDb, 1); - if( rc!=LSM_OK ) return rc; - pDb->pShmhdr = (ShmHeader *)pDb->apShm[0]; /* Block for an exclusive lock on DMS1. This lock serializes all calls ** to doDbConnect() and doDbDisconnect() across all processes. */ @@ -353,10 +350,11 @@ static int doDbConnect(lsm_db *pDb){ nUs = nUs * 2; if( nUs>nUsMax ) nUs = nUsMax; } - if( rc!=LSM_OK ){ - pDb->pShmhdr = 0; - return rc; + if( rc==LSM_OK ){ + rc = lsmShmCacheChunks(pDb, 1); } + if( rc!=LSM_OK ) return rc; + pDb->pShmhdr = (ShmHeader *)pDb->apShm[0]; /* Try an exclusive lock on DMS2/DMS3. If successful, this is the first ** and only connection to the database. In this case initialize the @@ -522,13 +520,11 @@ int lsmDbDatabaseConnect( ** recovery as necessary. Or, if this is a read-only database handle, ** defer attempting to connect to the system until a read-transaction ** is opened. */ - if( pDb->bReadonly==0 ){ - if( rc==LSM_OK ){ - rc = lsmFsConfigure(pDb); - } - if( rc==LSM_OK ){ - rc = doDbConnect(pDb); - } + if( rc==LSM_OK ){ + rc = lsmFsConfigure(pDb); + } + if( rc==LSM_OK && pDb->bReadonly==0 ){ + rc = doDbConnect(pDb); } return rc; diff --git a/ext/lsm1/lsm_sorted.c b/ext/lsm1/lsm_sorted.c index f479f4ce8c..4a24e4b829 100644 --- a/ext/lsm1/lsm_sorted.c +++ b/ext/lsm1/lsm_sorted.c @@ -92,7 +92,7 @@ #define SEGMENT_POINTER_OFFSET(pgsz) ((pgsz) - 2 - 2 - 8) #define SEGMENT_CELLPTR_OFFSET(pgsz, iCell) ((pgsz) - 2 - 2 - 8 - 2 - (iCell)*2) -#define SEGMENT_EOF(pgsz, nEntry) SEGMENT_CELLPTR_OFFSET(pgsz, nEntry) +#define SEGMENT_EOF(pgsz, nEntry) SEGMENT_CELLPTR_OFFSET(pgsz, nEntry-1) #define SEGMENT_BTREE_FLAG 0x0001 #define PGFTR_SKIP_NEXT_FLAG 0x0002 @@ -104,9 +104,9 @@ #endif typedef struct SegmentPtr SegmentPtr; -typedef struct Blob Blob; +typedef struct LsmBlob LsmBlob; -struct Blob { +struct LsmBlob { lsm_env *pEnv; void *pData; int nData; @@ -129,18 +129,18 @@ struct SegmentPtr { Page *pPg; /* Current page */ u16 flags; /* Copy of page flags field */ int nCell; /* Number of cells on pPg */ - Pgno iPtr; /* Base cascade pointer */ + LsmPgno iPtr; /* Base cascade pointer */ /* Current cell. See segmentPtrLoadCell() */ int iCell; /* Current record within page pPg */ int eType; /* Type of current record */ - Pgno iPgPtr; /* Cascade pointer offset */ + LsmPgno iPgPtr; /* Cascade pointer offset */ void *pKey; int nKey; /* Key associated with current record */ void *pVal; int nVal; /* Current record value (eType==WRITE only) */ /* Blobs used to allocate buffers for pKey and pVal as required */ - Blob blob1; - Blob blob2; + LsmBlob blob1; + LsmBlob blob2; }; /* @@ -171,10 +171,10 @@ struct BtreeCursor { void *pKey; int nKey; int eType; - Pgno iPtr; + LsmPgno iPtr; /* Storage for key, if not local */ - Blob blob; + LsmBlob blob; }; @@ -203,8 +203,8 @@ struct MultiCursor { int flags; /* Mask of CURSOR_XXX flags */ int eType; /* Cache of current key type */ - Blob key; /* Cache of current key (or NULL) */ - Blob val; /* Cache of current value */ + LsmBlob key; /* Cache of current key (or NULL) */ + LsmBlob val; /* Cache of current value */ /* All the component cursors: */ TreeCursor *apTreeCsr[2]; /* Up to two tree cursors */ @@ -221,7 +221,7 @@ struct MultiCursor { void *pSystemVal; /* Pointer to buffer to free */ /* Used by worker cursors only */ - Pgno *pPrevMergePtr; + LsmPgno *pPrevMergePtr; }; /* @@ -295,11 +295,11 @@ struct MergeWorker { Hierarchy hier; /* B-tree hierarchy under construction */ Page *pPage; /* Current output page */ int nWork; /* Number of calls to mergeWorkerNextPage() */ - Pgno *aGobble; /* Gobble point for each input segment */ + LsmPgno *aGobble; /* Gobble point for each input segment */ - Pgno iIndirect; + LsmPgno iIndirect; struct SavedPgno { - Pgno iPgno; + LsmPgno iPgno; int bStore; } aSave[2]; }; @@ -371,7 +371,7 @@ void lsmPutU64(u8 *aOut, u64 nVal){ aOut[7] = (u8)((nVal ) & 0xFF); } -static int sortedBlobGrow(lsm_env *pEnv, Blob *pBlob, int nData){ +static int sortedBlobGrow(lsm_env *pEnv, LsmBlob *pBlob, int nData){ assert( pBlob->pEnv==pEnv || (pBlob->pEnv==0 && pBlob->pData==0) ); if( pBlob->nAllocpData = lsmReallocOrFree(pEnv, pBlob->pData, nData); @@ -382,7 +382,7 @@ static int sortedBlobGrow(lsm_env *pEnv, Blob *pBlob, int nData){ return LSM_OK; } -static int sortedBlobSet(lsm_env *pEnv, Blob *pBlob, void *pData, int nData){ +static int sortedBlobSet(lsm_env *pEnv, LsmBlob *pBlob, void *pData, int nData){ if( sortedBlobGrow(pEnv, pBlob, nData) ) return LSM_NOMEM; memcpy(pBlob->pData, pData, nData); pBlob->nData = nData; @@ -390,15 +390,15 @@ static int sortedBlobSet(lsm_env *pEnv, Blob *pBlob, void *pData, int nData){ } #if 0 -static int sortedBlobCopy(Blob *pDest, Blob *pSrc){ +static int sortedBlobCopy(LsmBlob *pDest, LsmBlob *pSrc){ return sortedBlobSet(pDest, pSrc->pData, pSrc->nData); } #endif -static void sortedBlobFree(Blob *pBlob){ +static void sortedBlobFree(LsmBlob *pBlob){ assert( pBlob->pEnv || pBlob->pData==0 ); if( pBlob->pData ) lsmFree(pBlob->pEnv, pBlob->pData); - memset(pBlob, 0, sizeof(Blob)); + memset(pBlob, 0, sizeof(LsmBlob)); } static int sortedReadData( @@ -407,7 +407,7 @@ static int sortedReadData( int iOff, int nByte, void **ppData, - Blob *pBlob + LsmBlob *pBlob ){ int rc = LSM_OK; int iEnd; @@ -481,8 +481,8 @@ static int pageGetNRec(u8 *aData, int nData){ return (int)lsmGetU16(&aData[SEGMENT_NRECORD_OFFSET(nData)]); } -static Pgno pageGetPtr(u8 *aData, int nData){ - return (Pgno)lsmGetU64(&aData[SEGMENT_POINTER_OFFSET(nData)]); +static LsmPgno pageGetPtr(u8 *aData, int nData){ + return (LsmPgno)lsmGetU64(&aData[SEGMENT_POINTER_OFFSET(nData)]); } static int pageGetFlags(u8 *aData, int nData){ @@ -506,8 +506,8 @@ static int pageObjGetNRec(Page *pPg){ ** Return the decoded (possibly relative) pointer value stored in cell ** iCell from page aData/nData. */ -static Pgno pageGetRecordPtr(u8 *aData, int nData, int iCell){ - Pgno iRet; /* Return value */ +static LsmPgno pageGetRecordPtr(u8 *aData, int nData, int iCell){ + LsmPgno iRet; /* Return value */ u8 *aCell; /* Pointer to cell iCell */ assert( iCell=0 ); @@ -522,7 +522,7 @@ static u8 *pageGetKey( int iCell, /* Index of cell on page to read */ int *piTopic, /* OUT: Topic associated with this key */ int *pnKey, /* OUT: Size of key in bytes */ - Blob *pBlob /* If required, use this for dynamic memory */ + LsmBlob *pBlob /* If required, use this for dynamic memory */ ){ u8 *pKey; int nDummy; @@ -554,7 +554,7 @@ static int pageGetKeyCopy( Page *pPg, /* Page to read from */ int iCell, /* Index of cell on page to read */ int *piTopic, /* OUT: Topic associated with this key */ - Blob *pBlob /* If required, use this for dynamic memory */ + LsmBlob *pBlob /* If required, use this for dynamic memory */ ){ int rc = LSM_OK; int nKey; @@ -569,8 +569,8 @@ static int pageGetKeyCopy( return rc; } -static Pgno pageGetBtreeRef(Page *pPg, int iKey){ - Pgno iRef; +static LsmPgno pageGetBtreeRef(Page *pPg, int iKey){ + LsmPgno iRef; u8 *aData; int nData; u8 *aCell; @@ -592,11 +592,11 @@ static int pageGetBtreeKey( Segment *pSeg, /* Segment page pPg belongs to */ Page *pPg, int iKey, - Pgno *piPtr, + LsmPgno *piPtr, int *piTopic, void **ppKey, int *pnKey, - Blob *pBlob + LsmBlob *pBlob ){ u8 *aData; int nData; @@ -613,7 +613,7 @@ static int pageGetBtreeKey( if( eType==0 ){ int rc; - Pgno iRef; /* Page number of referenced page */ + LsmPgno iRef; /* Page number of referenced page */ Page *pRef; aCell += GETVARINT64(aCell, iRef); rc = lsmFsDbPageGet(lsmPageFS(pPg), pSeg, iRef, &pRef); @@ -638,7 +638,7 @@ static int btreeCursorLoadKey(BtreeCursor *pCsr){ pCsr->nKey = 0; pCsr->eType = 0; }else{ - Pgno dummy; + LsmPgno dummy; int iPg = pCsr->iPg; int iCell = pCsr->aPg[iPg].iCell; while( iCell<0 && (--iPg)>=0 ){ @@ -683,7 +683,7 @@ static int btreeCursorNext(BtreeCursor *pCsr){ assert( pPg->iCell<=nCell ); pPg->iCell++; if( pPg->iCell==nCell ){ - Pgno iLoad; + LsmPgno iLoad; /* Up to parent. */ lsmFsPageRelease(pPg->pPage); @@ -842,7 +842,7 @@ static int btreeCursorRestore( if( p->iPg ){ lsm_env *pEnv = lsmFsEnv(pCsr->pFS); int iCell; /* Current cell number on leaf page */ - Pgno iLeaf; /* Page number of current leaf page */ + LsmPgno iLeaf; /* Page number of current leaf page */ int nDepth; /* Depth of b-tree structure */ Segment *pSeg = pCsr->pSeg; @@ -866,7 +866,7 @@ static int btreeCursorRestore( /* Populate any other aPg[] array entries */ if( rc==LSM_OK && nDepth>1 ){ - Blob blob = {0,0,0}; + LsmBlob blob = {0,0,0}; void *pSeek; int nSeek; int iTopicSeek; @@ -883,7 +883,7 @@ static int btreeCursorRestore( pSeek = 0; nSeek = 0; }else{ - Pgno dummy; + LsmPgno dummy; rc = pageGetBtreeKey(pSeg, pPg, 0, &dummy, &iTopicSeek, &pSeek, &nSeek, &pCsr->blob ); @@ -912,7 +912,7 @@ static int btreeCursorRestore( int iTry = (iMin+iMax)/2; void *pKey; int nKey; /* Key for cell iTry */ int iTopic; /* Topic for key pKeyT/nKeyT */ - Pgno iPtr; /* Pointer for cell iTry */ + LsmPgno iPtr; /* Pointer for cell iTry */ int res; /* (pSeek - pKeyT) */ rc = pageGetBtreeKey( @@ -955,7 +955,7 @@ static int btreeCursorRestore( aData = fsPageData(pBtreePg->pPage, &nData); pCsr->iPtr = btreeCursorPtr(aData, nData, pBtreePg->iCell+1); if( pBtreePg->iCell<0 ){ - Pgno dummy; + LsmPgno dummy; int i; for(i=pCsr->iPg-1; i>=0; i--){ if( pCsr->aPg[i].iCell>0 ) break; @@ -1030,7 +1030,7 @@ static int segmentPtrReadData( int iOff, int nByte, void **ppData, - Blob *pBlob + LsmBlob *pBlob ){ return sortedReadData(pPtr->pSeg, pPtr->pPg, iOff, nByte, ppData, pBlob); } @@ -1123,7 +1123,7 @@ static void sortedSplitkey(lsm_db *pDb, Level *pLevel, int *pRc){ } if( rc==LSM_OK ){ int iTopic; - Blob blob = {0, 0, 0, 0}; + LsmBlob blob = {0, 0, 0, 0}; u8 *aData; int nData; @@ -1131,7 +1131,7 @@ static void sortedSplitkey(lsm_db *pDb, Level *pLevel, int *pRc){ if( pageGetFlags(aData, nData) & SEGMENT_BTREE_FLAG ){ void *pKey; int nKey; - Pgno dummy; + LsmPgno dummy; rc = pageGetBtreeKey(pSeg, pPg, pMerge->splitkey.iCell, &dummy, &iTopic, &pKey, &nKey, &blob ); @@ -1342,7 +1342,7 @@ static int assertKeyLocation( void *pKey, int nKey ){ lsm_env *pEnv = lsmFsEnv(pCsr->pDb->pFS); - Blob blob = {0, 0, 0}; + LsmBlob blob = {0, 0, 0}; int eDir; int iTopic = 0; /* TODO: Fix me */ @@ -1488,7 +1488,7 @@ static int ptrFwdPointer( Page *pPage, int iCell, Segment *pSeg, - Pgno *piPtr, + LsmPgno *piPtr, int *pbFound ){ Page *pPg = pPage; @@ -1573,14 +1573,14 @@ static int sortedRhsFirst(MultiCursor *pCsr, Level *pLvl, SegmentPtr *pPtr){ static int segmentPtrFwdPointer( MultiCursor *pCsr, /* Multi-cursor pPtr belongs to */ SegmentPtr *pPtr, /* Segment-pointer to extract FC ptr from */ - Pgno *piPtr /* OUT: FC pointer value */ + LsmPgno *piPtr /* OUT: FC pointer value */ ){ Level *pLvl = pPtr->pLevel; Level *pNext = pLvl->pNext; Page *pPg = pPtr->pPg; int rc; int bFound; - Pgno iOut = 0; + LsmPgno iOut = 0; if( pPtr->pSeg==&pLvl->lhs || pPtr->pSeg==&pLvl->aRhs[pLvl->nRight-1] ){ if( pNext==0 @@ -1641,7 +1641,7 @@ static int segmentPtrSeek( int rc = LSM_OK; int iMin; int iMax; - Pgno iPtrOut = 0; + LsmPgno iPtrOut = 0; /* If the current page contains an oversized entry, then there are no ** pointers to one or more of the subsequent pages in the sorted run. @@ -1768,18 +1768,18 @@ static int seekInBtree( Segment *pSeg, /* Seek within this segment */ int iTopic, void *pKey, int nKey, /* Key to seek to */ - Pgno *aPg, /* OUT: Page numbers */ + LsmPgno *aPg, /* OUT: Page numbers */ Page **ppPg /* OUT: Leaf (sorted-run) page reference */ ){ int i = 0; int rc; int iPg; Page *pPg = 0; - Blob blob = {0, 0, 0}; + LsmBlob blob = {0, 0, 0}; iPg = (int)pSeg->iRoot; do { - Pgno *piFirst = 0; + LsmPgno *piFirst = 0; if( aPg ){ aPg[i++] = iPg; piFirst = &aPg[i]; @@ -1808,7 +1808,7 @@ static int seekInBtree( int iTry = (iMin+iMax)/2; void *pKeyT; int nKeyT; /* Key for cell iTry */ int iTopicT; /* Topic for key pKeyT/nKeyT */ - Pgno iPtr; /* Pointer associated with cell iTry */ + LsmPgno iPtr; /* Pointer associated with cell iTry */ int res; /* (pKey - pKeyT) */ rc = pageGetBtreeKey( @@ -1899,7 +1899,7 @@ static int seekInLevel( int eSeek, /* Search bias - see above */ int iTopic, /* Key topic to search for */ void *pKey, int nKey, /* Key to search for */ - Pgno *piPgno, /* IN/OUT: fraction cascade pointer (or 0) */ + LsmPgno *piPgno, /* IN/OUT: fraction cascade pointer (or 0) */ int *pbStop /* OUT: See above */ ){ Level *pLvl = aPtr[0].pLevel; /* Level to seek within */ @@ -1922,6 +1922,7 @@ static int seekInLevel( ** is not a composite level and there is no split-key). Search the ** left-hand-side of the level in this case. */ if( res<0 ){ + int i; int iPtr = 0; if( nRhs==0 ) iPtr = (int)*piPgno; @@ -1931,12 +1932,16 @@ static int seekInLevel( if( rc==LSM_OK && nRhs>0 && eSeek==LSM_SEEK_GE && aPtr[0].pPg==0 ){ res = 0; } + for(i=1; i<=nRhs; i++){ + segmentPtrReset(&aPtr[i], LSM_SEGMENTPTR_FREE_THRESHOLD); + } } if( res>=0 ){ int bHit = 0; /* True if at least one rhs is not EOF */ int iPtr = (int)*piPgno; int i; + segmentPtrReset(&aPtr[0], LSM_SEGMENTPTR_FREE_THRESHOLD); for(i=1; rc==LSM_OK && i<=nRhs && bStop==0; i++){ SegmentPtr *pPtr = &aPtr[i]; iOut = 0; @@ -2868,7 +2873,7 @@ static int multiCursorEnd(MultiCursor *pCsr, int bLast){ int rc = LSM_OK; int i; - pCsr->flags &= ~(CURSOR_NEXT_OK | CURSOR_PREV_OK); + pCsr->flags &= ~(CURSOR_NEXT_OK | CURSOR_PREV_OK | CURSOR_SEEK_EQ); pCsr->flags |= (bLast ? CURSOR_PREV_OK : CURSOR_NEXT_OK); pCsr->iFree = 0; @@ -3055,7 +3060,7 @@ int lsmMCursorSeek( int bStop = 0; /* Set to true to halt search operation */ int rc = LSM_OK; /* Return code */ int iPtr = 0; /* Used to iterate through pCsr->aPtr[] */ - Pgno iPgno = 0; /* FC pointer value */ + LsmPgno iPgno = 0; /* FC pointer value */ assert( pCsr->apTreeCsr[0]==0 || iTopic==0 ); assert( pCsr->apTreeCsr[1]==0 || iTopic==0 ); @@ -3537,7 +3542,7 @@ static int mergeWorkerLoadHierarchy(MergeWorker *pMW){ ** + Type byte (always SORTED_SEPARATOR or SORTED_SYSTEM_SEPARATOR), ** + Absolute pointer value (varint), ** + Number of bytes in key (varint), -** + Blob containing key data. +** + LsmBlob containing key data. ** ** 2. All pointer values are stored as absolute values (not offsets ** relative to the footer pointer value). @@ -3571,8 +3576,8 @@ static int mergeWorkerLoadHierarchy(MergeWorker *pMW){ static int mergeWorkerBtreeWrite( MergeWorker *pMW, u8 eType, - Pgno iPtr, - Pgno iKeyPg, + LsmPgno iPtr, + LsmPgno iKeyPg, void *pKey, int nKey ){ @@ -3682,7 +3687,7 @@ static int mergeWorkerBtreeWrite( static int mergeWorkerBtreeIndirect(MergeWorker *pMW){ int rc = LSM_OK; if( pMW->iIndirect ){ - Pgno iKeyPg = pMW->aSave[1].iPgno; + LsmPgno iKeyPg = pMW->aSave[1].iPgno; rc = mergeWorkerBtreeWrite(pMW, 0, pMW->iIndirect, iKeyPg, 0, 0); pMW->iIndirect = 0; } @@ -3703,7 +3708,7 @@ static int mergeWorkerPushHierarchy( int nKey /* Size of pKey buffer in bytes */ ){ int rc = LSM_OK; /* Return Code */ - Pgno iPtr; /* Pointer value to accompany pKey/nKey */ + LsmPgno iPtr; /* Pointer value to accompany pKey/nKey */ assert( pMW->aSave[0].bStore==0 ); assert( pMW->aSave[1].bStore==0 ); @@ -3734,7 +3739,7 @@ static int mergeWorkerFinishHierarchy( ){ int i; /* Used to loop through apHier[] */ int rc = LSM_OK; /* Return code */ - Pgno iPtr; /* New right-hand-child pointer value */ + LsmPgno iPtr; /* New right-hand-child pointer value */ iPtr = pMW->aSave[0].iPgno; for(i=0; ihier.nHier && rc==LSM_OK; i++){ @@ -3830,7 +3835,7 @@ static int mergeWorkerPersistAndRelease(MergeWorker *pMW){ */ static int mergeWorkerNextPage( MergeWorker *pMW, /* Merge worker object to append page to */ - Pgno iFPtr /* Pointer value for footer of new page */ + LsmPgno iFPtr /* Pointer value for footer of new page */ ){ int rc = LSM_OK; /* Return code */ Page *pNext = 0; /* New page appended to run */ @@ -3999,6 +4004,11 @@ static int mergeWorkerWrite( ** marked read-only, advance to the next page of the output run. */ iOff = pMerge->iOutputOff; if( iOff<0 || pPg==0 || iOff+nHdr > SEGMENT_EOF(nData, nRec+1) ){ + if( iOff>=0 && pPg ){ + /* Zero any free space on the page */ + assert( aData ); + memset(&aData[iOff], 0, SEGMENT_EOF(nData, nRec)-iOff); + } iFPtr = (int)*pMW->pCsr->pPrevMergePtr; iRPtr = iPtr - iFPtr; iOff = 0; @@ -4069,36 +4079,49 @@ static void mergeWorkerShutdown(MergeWorker *pMW, int *pRc){ /* Unless the merge has finished, save the cursor position in the ** Merge.aInput[] array. See function mergeWorkerInit() for the ** code to restore a cursor position based on aInput[]. */ - if( rc==LSM_OK && pCsr && lsmMCursorValid(pCsr) ){ + if( rc==LSM_OK && pCsr ){ Merge *pMerge = pMW->pLevel->pMerge; - int bBtree = (pCsr->pBtCsr!=0); - int iPtr; + if( lsmMCursorValid(pCsr) ){ + int bBtree = (pCsr->pBtCsr!=0); + int iPtr; - /* pMerge->nInput==0 indicates that this is a FlushTree() operation. */ - assert( pMerge->nInput==0 || pMW->pLevel->nRight>0 ); - assert( pMerge->nInput==0 || pMerge->nInput==(pCsr->nPtr+bBtree) ); + /* pMerge->nInput==0 indicates that this is a FlushTree() operation. */ + assert( pMerge->nInput==0 || pMW->pLevel->nRight>0 ); + assert( pMerge->nInput==0 || pMerge->nInput==(pCsr->nPtr+bBtree) ); - for(i=0; i<(pMerge->nInput-bBtree); i++){ - SegmentPtr *pPtr = &pCsr->aPtr[i]; - if( pPtr->pPg ){ - pMerge->aInput[i].iPg = lsmFsPageNumber(pPtr->pPg); - pMerge->aInput[i].iCell = pPtr->iCell; + for(i=0; i<(pMerge->nInput-bBtree); i++){ + SegmentPtr *pPtr = &pCsr->aPtr[i]; + if( pPtr->pPg ){ + pMerge->aInput[i].iPg = lsmFsPageNumber(pPtr->pPg); + pMerge->aInput[i].iCell = pPtr->iCell; + }else{ + pMerge->aInput[i].iPg = 0; + pMerge->aInput[i].iCell = 0; + } + } + if( bBtree && pMerge->nInput ){ + assert( i==pCsr->nPtr ); + btreeCursorPosition(pCsr->pBtCsr, &pMerge->aInput[i]); + } + + /* Store the location of the split-key */ + iPtr = pCsr->aTree[1] - CURSOR_DATA_SEGMENT; + if( iPtrnPtr ){ + pMerge->splitkey = pMerge->aInput[iPtr]; }else{ - pMerge->aInput[i].iPg = 0; - pMerge->aInput[i].iCell = 0; + btreeCursorSplitkey(pCsr->pBtCsr, &pMerge->splitkey); } } - if( bBtree && pMerge->nInput ){ - assert( i==pCsr->nPtr ); - btreeCursorPosition(pCsr->pBtCsr, &pMerge->aInput[i]); - } - /* Store the location of the split-key */ - iPtr = pCsr->aTree[1] - CURSOR_DATA_SEGMENT; - if( iPtrnPtr ){ - pMerge->splitkey = pMerge->aInput[iPtr]; - }else{ - btreeCursorSplitkey(pCsr->pBtCsr, &pMerge->splitkey); + /* Zero any free space left on the final page. This helps with + ** compression if using a compression hook. And prevents valgrind + ** from complaining about uninitialized byte passed to write(). */ + if( pMW->pPage ){ + int nData; + u8 *aData = fsPageData(pMW->pPage, &nData); + int iOff = pMerge->iOutputOff; + int iEof = SEGMENT_EOF(nData, pageGetNRec(aData, nData)); + memset(&aData[iOff], 0, iEof - iOff); } pMerge->iOutputOff = -1; @@ -4200,7 +4223,7 @@ static int mergeWorkerStep(MergeWorker *pMW){ int rc = LSM_OK; /* Return code */ int eType; /* SORTED_SEPARATOR, WRITE or DELETE */ void *pKey; int nKey; /* Key */ - Pgno iPtr; + LsmPgno iPtr; int iVal; pCsr = pMW->pCsr; @@ -4353,7 +4376,7 @@ static int sortedNewToplevel( if( rc!=LSM_OK ){ lsmMCursorClose(pCsr, 0); }else{ - Pgno iLeftPtr = 0; + LsmPgno iLeftPtr = 0; Merge merge; /* Merge object used to create new level */ MergeWorker mergeworker; /* MergeWorker object for the same purpose */ @@ -4530,7 +4553,7 @@ static int mergeWorkerInit( memset(pMW, 0, sizeof(MergeWorker)); pMW->pDb = pDb; pMW->pLevel = pLevel; - pMW->aGobble = lsmMallocZeroRc(pDb->pEnv, sizeof(Pgno) * pLevel->nRight, &rc); + pMW->aGobble = lsmMallocZeroRc(pDb->pEnv, sizeof(LsmPgno)*pLevel->nRight,&rc); /* Create a multi-cursor to read the data to write to the new ** segment. The new segment contains: @@ -4612,7 +4635,7 @@ static int sortedBtreeGobble( int rc = LSM_OK; if( rtTopic(pCsr->eType)==0 ){ Segment *pSeg = pCsr->aPtr[iGobble].pSeg; - Pgno *aPg; + LsmPgno *aPg; int nPg; /* Seek from the root of the b-tree to the segment leaf that may contain @@ -4621,7 +4644,7 @@ static int sortedBtreeGobble( ** gobbled up to (but not including) the first of these page numbers. */ assert( pSeg->iRoot>0 ); - aPg = lsmMallocZeroRc(pDb->pEnv, sizeof(Pgno)*32, &rc); + aPg = lsmMallocZeroRc(pDb->pEnv, sizeof(LsmPgno)*32, &rc); if( rc==LSM_OK ){ rc = seekInBtree(pCsr, pSeg, rtTopic(pCsr->eType), pCsr->key.pData, pCsr->key.nData, aPg, 0 @@ -5234,16 +5257,15 @@ static int doLsmSingleWork( /* If the in-memory part of the free-list is too large, write a new ** top-level containing just the in-memory free-list entries to disk. */ if( rc==LSM_OK && pDb->pWorker->freelist.nEntry > pDb->nMaxFreelist ){ - int nPg = 0; while( rc==LSM_OK && lsmDatabaseFull(pDb) ){ + int nPg = 0; rc = sortedWork(pDb, 16, nMerge, 1, &nPg); nRem -= nPg; } if( rc==LSM_OK ){ rc = sortedNewFreelistOnly(pDb); } - nRem -= nPg; - if( nPg ) bDirty = 1; + bDirty = 1; } if( rc==LSM_OK ){ @@ -5448,9 +5470,9 @@ int lsmFlushTreeToDisk(lsm_db *pDb){ */ static char *segToString(lsm_env *pEnv, Segment *pSeg, int nMin){ int nSize = pSeg->nSize; - Pgno iRoot = pSeg->iRoot; - Pgno iFirst = pSeg->iFirst; - Pgno iLast = pSeg->iLastPg; + LsmPgno iRoot = pSeg->iRoot; + LsmPgno iFirst = pSeg->iFirst; + LsmPgno iLast = pSeg->iLastPg; char *z; char *z1; @@ -5509,7 +5531,7 @@ static int fileToString( } void sortedDumpPage(lsm_db *pDb, Segment *pRun, Page *pPg, int bVals){ - Blob blob = {0, 0, 0}; /* Blob used for keys */ + LsmBlob blob = {0, 0, 0}; /* LsmBlob used for keys */ LsmString s; int i; @@ -5545,7 +5567,7 @@ void sortedDumpPage(lsm_db *pDb, Segment *pRun, Page *pPg, int bVals){ aCell += lsmVarintGet32(aCell, &iPgPtr); if( eType==0 ){ - Pgno iRef; /* Page number of referenced page */ + LsmPgno iRef; /* Page number of referenced page */ aCell += lsmVarintGet64(aCell, &iRef); lsmFsDbPageGet(pDb->pFS, pRun, iRef, &pRef); aKey = pageGetKey(pRun, pRef, 0, &iTopic, &nKey, &blob); @@ -5589,7 +5611,7 @@ static void infoCellDump( int *piPgPtr, u8 **paKey, int *pnKey, u8 **paVal, int *pnVal, - Blob *pBlob + LsmBlob *pBlob ){ u8 *aData; int nData; /* Page data */ u8 *aKey; int nKey = 0; /* Key */ @@ -5607,7 +5629,7 @@ static void infoCellDump( if( eType==0 ){ int dummy; - Pgno iRef; /* Page number of referenced page */ + LsmPgno iRef; /* Page number of referenced page */ aCell += lsmVarintGet64(aCell, &iRef); if( bIndirect ){ lsmFsDbPageGet(pDb->pFS, pSeg, iRef, &pRef); @@ -5653,7 +5675,7 @@ static int infoAppendBlob(LsmString *pStr, int bHex, u8 *z, int n){ static int infoPageDump( lsm_db *pDb, /* Database handle */ - Pgno iPg, /* Page number of page to dump */ + LsmPgno iPg, /* Page number of page to dump */ int flags, char **pzOut /* OUT: lsmMalloc'd string */ ){ @@ -5694,7 +5716,7 @@ static int infoPageDump( } if( rc==LSM_OK ){ - Blob blob = {0, 0, 0, 0}; + LsmBlob blob = {0, 0, 0, 0}; int nKeyWidth = 0; LsmString str; int nRec; @@ -5729,7 +5751,7 @@ static int infoPageDump( u8 *aVal; int nVal = 0; /* Value */ int iPgPtr; int eType; - Pgno iAbsPtr; + LsmPgno iAbsPtr; char zFlags[8]; infoCellDump(pDb, pSeg, bIndirect, pPg, iCell, &eType, &iPgPtr, @@ -5795,7 +5817,7 @@ static int infoPageDump( int lsmInfoPageDump( lsm_db *pDb, /* Database handle */ - Pgno iPg, /* Page number of page to dump */ + LsmPgno iPg, /* Page number of page to dump */ int bHex, /* True to output key/value in hex form */ char **pzOut /* OUT: lsmMalloc'd string */ ){ @@ -5971,8 +5993,8 @@ void lsmSortedExpandBtreePage(Page *pPg, int nOrig){ #ifdef LSM_DEBUG_EXPENSIVE static void assertRunInOrder(lsm_db *pDb, Segment *pSeg){ Page *pPg = 0; - Blob blob1 = {0, 0, 0, 0}; - Blob blob2 = {0, 0, 0, 0}; + LsmBlob blob1 = {0, 0, 0, 0}; + LsmBlob blob2 = {0, 0, 0, 0}; lsmFsDbPageGet(pDb->pFS, pSeg, pSeg->iFirst, &pPg); while( pPg ){ @@ -6034,7 +6056,7 @@ static int assertPointersOk( int rc = LSM_OK; /* Error code */ SegmentPtr ptr1; /* Iterates through pOne */ SegmentPtr ptr2; /* Iterates through pTwo */ - Pgno iPrev; + LsmPgno iPrev; assert( pOne && pTwo ); @@ -6057,7 +6079,7 @@ static int assertPointersOk( } while( rc==LSM_OK && ptr2.pPg ){ - Pgno iThis; + LsmPgno iThis; /* Advance to the next page of segment pTwo that contains at least ** one cell. Break out of the loop if the iterator reaches EOF. */ @@ -6119,7 +6141,7 @@ static int assertBtreeOk( ){ int rc = LSM_OK; /* Return code */ if( pSeg->iRoot ){ - Blob blob = {0, 0, 0}; /* Buffer used to cache overflow keys */ + LsmBlob blob = {0, 0, 0}; /* Buffer used to cache overflow keys */ FileSystem *pFS = pDb->pFS; /* File system to read from */ Page *pPg = 0; /* Main run page */ BtreeCursor *pCsr = 0; /* Btree cursor */ diff --git a/ext/lsm1/lsm_vtab.c b/ext/lsm1/lsm_vtab.c index 5d7ca05fa5..fe7c160b62 100644 --- a/ext/lsm1/lsm_vtab.c +++ b/ext/lsm1/lsm_vtab.c @@ -10,16 +10,54 @@ ** ************************************************************************* ** -** This file implements a simple virtual table wrapper around the LSM +** This file implements a virtual table for SQLite3 around the LSM ** storage engine from SQLite4. ** ** USAGE ** ** CREATE VIRTUAL TABLE demo USING lsm1(filename,key,keytype,value1,...); ** +** The filename parameter is the name of the LSM database file, which is +** separate and distinct from the SQLite3 database file. +** ** The keytype must be one of: UINT, TEXT, BLOB. All keys must be of that -** one type. "UINT" means unsigned integer. The values may be any -** SQLite datatype. +** one type. "UINT" means unsigned integer. The values may be of any +** SQLite datatype: BLOB, TEXT, INTEGER, FLOAT, or NULL. +** +** The virtual table contains read-only hidden columns: +** +** lsm1_key A BLOB which is the raw LSM key. If the "keytype" +** is BLOB or TEXT then this column is exactly the +** same as the key. For the UINT keytype, this column +** will be a variable-length integer encoding of the key. +** +** lsm1_value A BLOB which is the raw LSM value. All of the value +** columns are packed into this BLOB using the encoding +** described below. +** +** Attempts to write values into the lsm1_key and lsm1_value columns are +** silently ignored. +** +** EXAMPLE +** +** The virtual table declared this way: +** +** CREATE VIRTUAL TABLE demo2 USING lsm1('x.lsm',id,UINT,a,b,c,d); +** +** Results in a new virtual table named "demo2" that acts as if it has +** the following schema: +** +** CREATE TABLE demo2( +** id UINT PRIMARY KEY ON CONFLICT REPLACE, +** a ANY, +** b ANY, +** c ANY, +** d ANY, +** lsm1_key BLOB HIDDEN, +** lsm1_value BLOB HIDDEN +** ) WITHOUT ROWID; +** +** ** ** INTERNALS ** @@ -243,13 +281,16 @@ static int lsm1Connect( lsm1VblobAppendText(&sql, argv[4]); lsm1VblobAppendText(&sql, " "); lsm1VblobAppendText(&sql, argv[5]); + lsm1VblobAppendText(&sql, " PRIMARY KEY"); for(i=6; inVal++; } lsm1VblobAppendText(&sql, - ", lsm1_command HIDDEN, lsm1_key HIDDEN, lsm1_value HIDDEN)"); + ", lsm1_command HIDDEN" + ", lsm1_key HIDDEN" + ", lsm1_value HIDDEN) WITHOUT ROWID"); lsm1VblobAppend(&sql, (u8*)"", 1); if( sql.errNoMem ){ rc = SQLITE_NOMEM; @@ -669,6 +710,31 @@ static int lsm1Column( return SQLITE_OK; } +/* Parameter "pValue" contains an SQL value that is to be used as +** a key in an LSM table. The type of the key is determined by +** "keyType". Extract the raw bytes used for the key in LSM1. +*/ +static void lsm1KeyFromValue( + int keyType, /* The key type */ + sqlite3_value *pValue, /* The key value */ + u8 *pBuf, /* Storage space for a generated key */ + const u8 **ppKey, /* OUT: the bytes of the key */ + int *pnKey /* OUT: size of the key */ +){ + if( keyType==SQLITE_BLOB ){ + *ppKey = (const u8*)sqlite3_value_blob(pValue); + *pnKey = sqlite3_value_bytes(pValue); + }else if( keyType==SQLITE_TEXT ){ + *ppKey = (const u8*)sqlite3_value_text(pValue); + *pnKey = sqlite3_value_bytes(pValue); + }else{ + sqlite3_int64 v = sqlite3_value_int64(pValue); + if( v<0 ) v = 0; + *pnKey = lsm1PutVarint64(pBuf, v); + *ppKey = pBuf; + } +} + /* Move to the first row to return. */ static int lsm1Filter( @@ -680,7 +746,7 @@ static int lsm1Filter( lsm1_vtab *pTab = (lsm1_vtab*)(pCur->base.pVtab); int rc = LSM_OK; int seekType = -1; - const void *pVal = 0; + const u8 *pVal = 0; int nVal; u8 keyType = pTab->keyType; u8 aKey1[16]; @@ -689,18 +755,7 @@ static int lsm1Filter( sqlite3_free(pCur->pKey2); pCur->pKey2 = 0; if( idxNum<99 ){ - if( keyType==SQLITE_BLOB ){ - pVal = sqlite3_value_blob(argv[0]); - nVal = sqlite3_value_bytes(argv[0]); - }else if( keyType==SQLITE_TEXT ){ - pVal = sqlite3_value_text(argv[0]); - nVal = sqlite3_value_bytes(argv[0]); - }else{ - sqlite3_int64 v = sqlite3_value_int64(argv[0]); - if( v<0 ) v = 0; - nVal = lsm1PutVarint64(aKey1, v); - pVal = aKey1; - } + lsm1KeyFromValue(keyType, argv[0], aKey1, &pVal, &nVal); } switch( idxNum ){ case 0: { /* key==argv[0] */ @@ -870,21 +925,30 @@ int lsm1Update( sqlite_int64 *pRowid ){ lsm1_vtab *p = (lsm1_vtab*)pVTab; - int nKey; + int nKey, nKey2; int i; int rc = LSM_OK; - unsigned char *pKey; + const u8 *pKey, *pKey2; unsigned char aKey[16]; unsigned char pSpace[16]; lsm1_vblob val; if( argc==1 ){ - pVTab->zErrMsg = sqlite3_mprintf("cannot DELETE"); - return SQLITE_ERROR; + /* DELETE the record whose key is argv[0] */ + lsm1KeyFromValue(p->keyType, argv[0], aKey, &pKey, &nKey); + lsm_delete(p->pDb, pKey, nKey); + return SQLITE_OK; } + if( sqlite3_value_type(argv[0])!=SQLITE_NULL ){ - pVTab->zErrMsg = sqlite3_mprintf("cannot UPDATE"); - return SQLITE_ERROR; + /* An UPDATE */ + lsm1KeyFromValue(p->keyType, argv[0], aKey, &pKey, &nKey); + lsm1KeyFromValue(p->keyType, argv[1], pSpace, &pKey2, &nKey2); + if( nKey!=nKey2 || memcmp(pKey, pKey2, nKey)!=0 ){ + /* The UPDATE changes the PRIMARY KEY value. DELETE the old key */ + lsm_delete(p->pDb, pKey, nKey); + } + /* Fall through into the INSERT case to complete the UPDATE */ } /* "INSERT INTO tab(lsm1_command) VALUES('....')" is used to implement @@ -893,22 +957,7 @@ int lsm1Update( if( sqlite3_value_type(argv[3+p->nVal])!=SQLITE_NULL ){ return SQLITE_OK; } - if( p->keyType==SQLITE_BLOB ){ - pKey = (u8*)sqlite3_value_blob(argv[2]); - nKey = sqlite3_value_bytes(argv[2]); - }else if( p->keyType==SQLITE_TEXT ){ - pKey = (u8*)sqlite3_value_text(argv[2]); - nKey = sqlite3_value_bytes(argv[2]); - }else{ - sqlite3_int64 v = sqlite3_value_int64(argv[2]); - if( v>=0 ){ - nKey = lsm1PutVarint64(aKey, (sqlite3_uint64)v); - pKey = aKey; - }else{ - pVTab->zErrMsg = sqlite3_mprintf("key must be non-negative"); - return SQLITE_ERROR; - } - } + lsm1KeyFromValue(p->keyType, argv[2], aKey, &pKey, &nKey); memset(&val, 0, sizeof(val)); for(i=0; inVal; i++){ sqlite3_value *pArg = argv[3+i]; diff --git a/ext/lsm1/test/lsm1_simple.test b/ext/lsm1/test/lsm1_simple.test index fd09d64676..bc0cb4c660 100644 --- a/ext/lsm1/test/lsm1_simple.test +++ b/ext/lsm1/test/lsm1_simple.test @@ -19,37 +19,75 @@ load_lsm1_vtab db forcedelete testlsm.db -do_execsql_test 1.0 { +do_execsql_test 100 { CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,UINT,b,c,d); PRAGMA table_info(x1); } { - 0 a UINT 0 {} 0 + 0 a UINT 1 {} 1 1 b {} 0 {} 0 2 c {} 0 {} 0 3 d {} 0 {} 0 } -do_execsql_test 1.1 { +do_execsql_test 110 { INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33),(8,'banjo',x'333231',NULL), (12,NULL,3.25,-559281390); SELECT a, quote(b), quote(c), quote(d) FROM x1; } {8 'banjo' X'333231' NULL 12 NULL 3.25 -559281390 15 11 22 33} +do_execsql_test 111 { + SELECT a, quote(lsm1_key), quote(lsm1_value) FROM x1; +} {8 X'08' X'2162616E6A6F1633323105' 12 X'0C' X'05320000000000000A401FFB42ABE9DB' 15 X'0F' X'4284C6'} -do_catchsql_test 1.2 { +do_execsql_test 120 { UPDATE x1 SET d = d+1.0 WHERE a=15; -} {1 {cannot UPDATE}} + SELECT a, quote(b), quote(c), quote(d) FROM x1; +} {8 'banjo' X'333231' NULL 12 NULL 3.25 -559281390 15 11 22 34.0} -do_catchsql_test 1.3 { +do_execsql_test 130 { + UPDATE x1 SET a=123456789 WHERE a=12; + SELECT a, quote(b), quote(c), quote(d) FROM x1; +} {8 'banjo' X'333231' NULL 15 11 22 34.0 123456789 NULL 3.25 -559281390} +do_execsql_test 131 { + SELECT quote(lsm1_key), printf('0x%x',a) FROM x1 WHERE a > 100000000; +} {X'FB075BCD15' 0x75bcd15} + +do_execsql_test 140 { DELETE FROM x1 WHERE a=15; -} {1 {cannot DELETE}} + SELECT a, quote(b), quote(c), quote(d) FROM x1; +} {8 'banjo' X'333231' NULL 123456789 NULL 3.25 -559281390} -do_test 1.4 { +do_test 150 { lsort [glob testlsm.db*] } {testlsm.db testlsm.db-log testlsm.db-shm} db close -do_test 1.5 { +do_test 160 { lsort [glob testlsm.db*] } {testlsm.db} +forcedelete testlsm.db +forcedelete test.db +sqlite3 db test.db +load_lsm1_vtab db + + +do_execsql_test 200 { + CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d); + PRAGMA table_info(x1); +} { + 0 a TEXT 1 {} 1 + 1 b {} 0 {} 0 + 2 c {} 0 {} 0 + 3 d {} 0 {} 0 +} +do_execsql_test 210 { + INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33),(8,'banjo',x'333231',NULL), + (12,NULL,3.25,-559281390); + SELECT quote(a), quote(b), quote(c), quote(d), '|' FROM x1; +} {'12' NULL 3.25 -559281390 | '15' 11 22 33 | '8' 'banjo' X'333231' NULL |} +do_execsql_test 211 { + SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1; +} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |} + + finish_test diff --git a/ext/lsm1/tool/mklsm1c.tcl b/ext/lsm1/tool/mklsm1c.tcl new file mode 100644 index 0000000000..d4a317b700 --- /dev/null +++ b/ext/lsm1/tool/mklsm1c.tcl @@ -0,0 +1,88 @@ +#!/bin/sh +# restart with tclsh \ +exec tclsh "$0" "$@" + +set srcdir [file dirname [file dirname [info script]]] +set G(src) [string map [list %dir% $srcdir] { + %dir%/lsm.h + %dir%/lsmInt.h + %dir%/lsm_vtab.c + %dir%/lsm_ckpt.c + %dir%/lsm_file.c + %dir%/lsm_log.c + %dir%/lsm_main.c + %dir%/lsm_mem.c + %dir%/lsm_mutex.c + %dir%/lsm_shared.c + %dir%/lsm_sorted.c + %dir%/lsm_str.c + %dir%/lsm_tree.c + %dir%/lsm_unix.c + %dir%/lsm_varint.c + %dir%/lsm_win32.c +}] + +set G(hdr) { + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_LSM1) + +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif +#if defined(NDEBUG) && defined(SQLITE_DEBUG) +# undef NDEBUG +#endif + +} + +set G(footer) { + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_LSM1) */ +} + +#------------------------------------------------------------------------- +# Read and return the entire contents of text file $zFile from disk. +# +proc readfile {zFile} { + set fd [open $zFile] + set data [read $fd] + close $fd + return $data +} + +proc lsm1c_init {zOut} { + global G + set G(fd) stdout + set G(fd) [open $zOut w] + + puts -nonewline $G(fd) $G(hdr) +} + +proc lsm1c_printfile {zIn} { + global G + set data [readfile $zIn] + set zTail [file tail $zIn] + puts $G(fd) "#line 1 \"$zTail\"" + + foreach line [split $data "\n"] { + if {[regexp {^# *include.*lsm} $line]} { + set line "/* $line */" + } elseif { [regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?lsm[^_]} $line] } { + set line "static $line" + } + puts $G(fd) $line + } +} + +proc lsm1c_close {} { + global G + puts -nonewline $G(fd) $G(footer) + if {$G(fd)!="stdout"} { + close $G(fd) + } +} + + +lsm1c_init lsm1.c +foreach f $G(src) { lsm1c_printfile $f } +lsm1c_close diff --git a/ext/misc/README.md b/ext/misc/README.md index 970a09c2e9..69cb230255 100644 --- a/ext/misc/README.md +++ b/ext/misc/README.md @@ -14,11 +14,20 @@ as follows: It is a good example of how to go about implementing a custom [table-valued function](https://www.sqlite.org/vtab.html#tabfunc2). + * **csv.c** — A [virtual table](https://sqlite.org/vtab.html) + for reading + [Comma-Separated-Value (CSV) files](https://en.wikipedia.org/wiki/Comma-separated_values). + * **dbdump.c** — This is not actually a loadable extension, but rather a library that implements an approximate equivalent to the ".dump" command of the [command-line shell](https://www.sqlite.org/cli.html). + * **json1.c** — Various SQL functions and table-valued functions + for processing JSON. This extension is already built into the + [SQLite amalgamation](https://sqlite.org/amalgamation.html). See + for additional information. + * **memvfs.c** — This file implements a custom [VFS](https://www.sqlite.org/vfs.html) that stores an entire database file in a single block of RAM. It serves as a good example of how @@ -38,3 +47,14 @@ as follows: on the source filename with digits removed, so if we used the name "sha3.c" then the entry point would conflict with the prior "sha1.c" extension. + + * **unionvtab.c** — Implementation of the unionvtab and + [swarmvtab](https://sqlite.org/swarmvtab.html) virtual tables. + These virtual tables allow a single + large table to be spread out across multiple database files. In the + case of swarmvtab, the individual database files can be attached on + demand. + + * **zipfile.c** — A [virtual table](https://sqlite.org/vtab.html) + that can read and write a + [ZIP archive](https://en.wikipedia.org/wiki/Zip_%28file_format%29). diff --git a/ext/misc/appendvfs.c b/ext/misc/appendvfs.c new file mode 100644 index 0000000000..b224245f3d --- /dev/null +++ b/ext/misc/appendvfs.c @@ -0,0 +1,565 @@ +/* +** 2017-10-20 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file implements a VFS shim that allows an SQLite database to be +** appended onto the end of some other file, such as an executable. +** +** A special record must appear at the end of the file that identifies the +** file as an appended database and provides an offset to page 1. For +** best performance page 1 should be located at a disk page boundary, though +** that is not required. +** +** When opening a database using this VFS, the connection might treat +** the file as an ordinary SQLite database, or it might treat is as a +** database appended onto some other file. Here are the rules: +** +** (1) When opening a new empty file, that file is treated as an ordinary +** database. +** +** (2) When opening a file that begins with the standard SQLite prefix +** string "SQLite format 3", that file is treated as an ordinary +** database. +** +** (3) When opening a file that ends with the appendvfs trailer string +** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended +** database. +** +** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is +** set, then a new database is appended to the already existing file. +** +** (5) Otherwise, SQLITE_CANTOPEN is returned. +** +** To avoid unnecessary complications with the PENDING_BYTE, the size of +** the file containing the database is limited to 1GB. This VFS will refuse +** to read or write past the 1GB mark. This restriction might be lifted in +** future versions. For now, if you need a large database, then keep the +** database in a separate file. +** +** If the file being opened is not an appended database, then this shim is +** a pass-through into the default underlying VFS. +**/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +/* The append mark at the end of the database is: +** +** Start-Of-SQLite3-NNNNNNNN +** 123456789 123456789 12345 +** +** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is +** the offset to page 1. +*/ +#define APND_MARK_PREFIX "Start-Of-SQLite3-" +#define APND_MARK_PREFIX_SZ 17 +#define APND_MARK_SIZE 25 + +/* +** Maximum size of the combined prefix + database + append-mark. This +** must be less than 0x40000000 to avoid locking issues on Windows. +*/ +#define APND_MAX_SIZE (65536*15259) + +/* +** Forward declaration of objects used by this utility +*/ +typedef struct sqlite3_vfs ApndVfs; +typedef struct ApndFile ApndFile; + +/* Access to a lower-level VFS that (might) implement dynamic loading, +** access to randomness, etc. +*/ +#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) +#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1)) + +/* An open file */ +struct ApndFile { + sqlite3_file base; /* IO methods */ + sqlite3_int64 iPgOne; /* File offset to page 1 */ + sqlite3_int64 iMark; /* Start of the append-mark */ +}; + +/* +** Methods for ApndFile +*/ +static int apndClose(sqlite3_file*); +static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); +static int apndTruncate(sqlite3_file*, sqlite3_int64 size); +static int apndSync(sqlite3_file*, int flags); +static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int apndLock(sqlite3_file*, int); +static int apndUnlock(sqlite3_file*, int); +static int apndCheckReservedLock(sqlite3_file*, int *pResOut); +static int apndFileControl(sqlite3_file*, int op, void *pArg); +static int apndSectorSize(sqlite3_file*); +static int apndDeviceCharacteristics(sqlite3_file*); +static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); +static int apndShmLock(sqlite3_file*, int offset, int n, int flags); +static void apndShmBarrier(sqlite3_file*); +static int apndShmUnmap(sqlite3_file*, int deleteFlag); +static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); +static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); + +/* +** Methods for ApndVfs +*/ +static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir); +static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *apndDlOpen(sqlite3_vfs*, const char *zFilename); +static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); +static void apndDlClose(sqlite3_vfs*, void*); +static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int apndSleep(sqlite3_vfs*, int microseconds); +static int apndCurrentTime(sqlite3_vfs*, double*); +static int apndGetLastError(sqlite3_vfs*, int, char *); +static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); +static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr); +static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z); +static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName); + +static sqlite3_vfs apnd_vfs = { + 3, /* iVersion (set when registered) */ + 0, /* szOsFile (set when registered) */ + 1024, /* mxPathname */ + 0, /* pNext */ + "apndvfs", /* zName */ + 0, /* pAppData (set when registered) */ + apndOpen, /* xOpen */ + apndDelete, /* xDelete */ + apndAccess, /* xAccess */ + apndFullPathname, /* xFullPathname */ + apndDlOpen, /* xDlOpen */ + apndDlError, /* xDlError */ + apndDlSym, /* xDlSym */ + apndDlClose, /* xDlClose */ + apndRandomness, /* xRandomness */ + apndSleep, /* xSleep */ + apndCurrentTime, /* xCurrentTime */ + apndGetLastError, /* xGetLastError */ + apndCurrentTimeInt64, /* xCurrentTimeInt64 */ + apndSetSystemCall, /* xSetSystemCall */ + apndGetSystemCall, /* xGetSystemCall */ + apndNextSystemCall /* xNextSystemCall */ +}; + +static const sqlite3_io_methods apnd_io_methods = { + 3, /* iVersion */ + apndClose, /* xClose */ + apndRead, /* xRead */ + apndWrite, /* xWrite */ + apndTruncate, /* xTruncate */ + apndSync, /* xSync */ + apndFileSize, /* xFileSize */ + apndLock, /* xLock */ + apndUnlock, /* xUnlock */ + apndCheckReservedLock, /* xCheckReservedLock */ + apndFileControl, /* xFileControl */ + apndSectorSize, /* xSectorSize */ + apndDeviceCharacteristics, /* xDeviceCharacteristics */ + apndShmMap, /* xShmMap */ + apndShmLock, /* xShmLock */ + apndShmBarrier, /* xShmBarrier */ + apndShmUnmap, /* xShmUnmap */ + apndFetch, /* xFetch */ + apndUnfetch /* xUnfetch */ +}; + + + +/* +** Close an apnd-file. +*/ +static int apndClose(sqlite3_file *pFile){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xClose(pFile); +} + +/* +** Read data from an apnd-file. +*/ +static int apndRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + ApndFile *p = (ApndFile *)pFile; + pFile = ORIGFILE(pFile); + return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne); +} + +/* +** Add the append-mark onto the end of the file. +*/ +static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){ + int i; + unsigned char a[APND_MARK_SIZE]; + memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); + for(i=0; i<8; i++){ + a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff; + } + return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark); +} + +/* +** Write data to an apnd-file. +*/ +static int apndWrite( + sqlite3_file *pFile, + const void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + int rc; + ApndFile *p = (ApndFile *)pFile; + pFile = ORIGFILE(pFile); + if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL; + rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne); + if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){ + sqlite3_int64 sz = 0; + rc = pFile->pMethods->xFileSize(pFile, &sz); + if( rc==SQLITE_OK ){ + p->iMark = sz - APND_MARK_SIZE; + if( iOfst + iAmt + p->iPgOne > p->iMark ){ + p->iMark = p->iPgOne + iOfst + iAmt; + rc = apndWriteMark(p, pFile); + } + } + } + return rc; +} + +/* +** Truncate an apnd-file. +*/ +static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){ + int rc; + ApndFile *p = (ApndFile *)pFile; + pFile = ORIGFILE(pFile); + rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE); + if( rc==SQLITE_OK ){ + p->iMark = p->iPgOne+size; + rc = apndWriteMark(p, pFile); + } + return rc; +} + +/* +** Sync an apnd-file. +*/ +static int apndSync(sqlite3_file *pFile, int flags){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xSync(pFile, flags); +} + +/* +** Return the current file-size of an apnd-file. +*/ +static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + ApndFile *p = (ApndFile *)pFile; + int rc; + pFile = ORIGFILE(p); + rc = pFile->pMethods->xFileSize(pFile, pSize); + if( rc==SQLITE_OK && p->iPgOne ){ + *pSize -= p->iPgOne + APND_MARK_SIZE; + } + return rc; +} + +/* +** Lock an apnd-file. +*/ +static int apndLock(sqlite3_file *pFile, int eLock){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xLock(pFile, eLock); +} + +/* +** Unlock an apnd-file. +*/ +static int apndUnlock(sqlite3_file *pFile, int eLock){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xUnlock(pFile, eLock); +} + +/* +** Check if another file-handle holds a RESERVED lock on an apnd-file. +*/ +static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xCheckReservedLock(pFile, pResOut); +} + +/* +** File control method. For custom operations on an apnd-file. +*/ +static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){ + ApndFile *p = (ApndFile *)pFile; + int rc; + pFile = ORIGFILE(pFile); + rc = pFile->pMethods->xFileControl(pFile, op, pArg); + if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ + *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg); + } + return rc; +} + +/* +** Return the sector-size in bytes for an apnd-file. +*/ +static int apndSectorSize(sqlite3_file *pFile){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xSectorSize(pFile); +} + +/* +** Return the device characteristic flags supported by an apnd-file. +*/ +static int apndDeviceCharacteristics(sqlite3_file *pFile){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xDeviceCharacteristics(pFile); +} + +/* Create a shared memory file mapping */ +static int apndShmMap( + sqlite3_file *pFile, + int iPg, + int pgsz, + int bExtend, + void volatile **pp +){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp); +} + +/* Perform locking on a shared-memory segment */ +static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xShmLock(pFile,offset,n,flags); +} + +/* Memory barrier operation on shared memory */ +static void apndShmBarrier(sqlite3_file *pFile){ + pFile = ORIGFILE(pFile); + pFile->pMethods->xShmBarrier(pFile); +} + +/* Unmap a shared memory segment */ +static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){ + pFile = ORIGFILE(pFile); + return pFile->pMethods->xShmUnmap(pFile,deleteFlag); +} + +/* Fetch a page of a memory-mapped file */ +static int apndFetch( + sqlite3_file *pFile, + sqlite3_int64 iOfst, + int iAmt, + void **pp +){ + ApndFile *p = (ApndFile *)pFile; + pFile = ORIGFILE(pFile); + return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp); +} + +/* Release a memory-mapped page */ +static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ + ApndFile *p = (ApndFile *)pFile; + pFile = ORIGFILE(pFile); + return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage); +} + +/* +** Check to see if the file is an ordinary SQLite database file. +*/ +static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ + int rc; + char zHdr[16]; + static const char aSqliteHdr[] = "SQLite format 3"; + if( sz<512 ) return 0; + rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0); + if( rc ) return 0; + return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0; +} + +/* +** Try to read the append-mark off the end of a file. Return the +** start of the appended database if the append-mark is present. If +** there is no append-mark, return -1; +*/ +static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){ + int rc, i; + sqlite3_int64 iMark; + unsigned char a[APND_MARK_SIZE]; + + if( sz<=APND_MARK_SIZE ) return -1; + rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE); + if( rc ) return -1; + if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1; + iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56; + for(i=1; i<8; i++){ + iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i); + } + return iMark; +} + +/* +** Open an apnd file handle. +*/ +static int apndOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFile, + int flags, + int *pOutFlags +){ + ApndFile *p; + sqlite3_file *pSubFile; + sqlite3_vfs *pSubVfs; + int rc; + sqlite3_int64 sz; + pSubVfs = ORIGVFS(pVfs); + if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ + return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags); + } + p = (ApndFile*)pFile; + memset(p, 0, sizeof(*p)); + pSubFile = ORIGFILE(pFile); + p->base.pMethods = &apnd_io_methods; + rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags); + if( rc ) goto apnd_open_done; + rc = pSubFile->pMethods->xFileSize(pSubFile, &sz); + if( rc ){ + pSubFile->pMethods->xClose(pSubFile); + goto apnd_open_done; + } + if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){ + memmove(pFile, pSubFile, pSubVfs->szOsFile); + return SQLITE_OK; + } + p->iMark = 0; + p->iPgOne = apndReadMark(sz, pFile); + if( p->iPgOne>0 ){ + return SQLITE_OK; + } + if( (flags & SQLITE_OPEN_CREATE)==0 ){ + pSubFile->pMethods->xClose(pSubFile); + rc = SQLITE_CANTOPEN; + } + p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff; +apnd_open_done: + if( rc ) pFile->pMethods = 0; + return rc; +} + +/* +** All other VFS methods are pass-thrus. +*/ +static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); +} +static int apndAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut); +} +static int apndFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut); +} +static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); +} +static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); +} +static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ + return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); +} +static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){ + ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); +} +static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); +} +static int apndSleep(sqlite3_vfs *pVfs, int nMicro){ + return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); +} +static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); +} +static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); +} +static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ + return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); +} +static int apndSetSystemCall( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_syscall_ptr pCall +){ + return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall); +} +static sqlite3_syscall_ptr apndGetSystemCall( + sqlite3_vfs *pVfs, + const char *zName +){ + return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName); +} +static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){ + return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName); +} + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +/* +** This routine is called when the extension is loaded. +** Register the new VFS. +*/ +int sqlite3_appendvfs_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + sqlite3_vfs *pOrig; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; + (void)db; + pOrig = sqlite3_vfs_find(0); + apnd_vfs.iVersion = pOrig->iVersion; + apnd_vfs.pAppData = pOrig; + apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile); + rc = sqlite3_vfs_register(&apnd_vfs, 0); +#ifdef APPENDVFS_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister); + } +#endif + if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; + return rc; +} diff --git a/ext/misc/btreeinfo.c b/ext/misc/btreeinfo.c new file mode 100644 index 0000000000..131b210a79 --- /dev/null +++ b/ext/misc/btreeinfo.c @@ -0,0 +1,428 @@ +/* +** 2017-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 contains an implementation of the "sqlite_btreeinfo" virtual table. +** +** The sqlite_btreeinfo virtual table is a read-only eponymous-only virtual +** table that shows information about all btrees in an SQLite database file. +** The schema is like this: +** +** CREATE TABLE sqlite_btreeinfo( +** type TEXT, -- "table" or "index" +** name TEXT, -- Name of table or index for this btree. +** tbl_name TEXT, -- Associated table +** rootpage INT, -- The root page of the btree +** sql TEXT, -- SQL for this btree - from sqlite_master +** hasRowid BOOLEAN, -- True if the btree has a rowid +** nEntry INT, -- Estimated number of enteries +** nPage INT, -- Estimated number of pages +** depth INT, -- Depth of the btree +** szPage INT, -- Size of each page in bytes +** zSchema TEXT HIDDEN -- The schema to which this btree belongs +** ); +** +** The first 5 fields are taken directly from the sqlite_master table. +** Considering only the first 5 fields, the only difference between +** this virtual table and the sqlite_master table is that this virtual +** table omits all entries that have a 0 or NULL rowid - in other words +** it omits triggers and views. +** +** The value added by this table comes in the next 5 fields. +** +** Note that nEntry and nPage are *estimated*. They are computed doing +** a single search from the root to a leaf, counting the number of cells +** at each level, and assuming that unvisited pages have a similar number +** of cells. +** +** The sqlite_dbpage virtual table must be available for this virtual table +** to operate. +** +** USAGE EXAMPLES: +** +** Show the table btrees in a schema order with the tables with the most +** rows occuring first: +** +** SELECT name, nEntry +** FROM sqlite_btreeinfo +** WHERE type='table' +** ORDER BY nEntry DESC, name; +** +** Show the names of all WITHOUT ROWID tables: +** +** SELECT name FROM sqlite_btreeinfo +** WHERE type='table' AND NOT hasRowid; +*/ +#if !defined(SQLITEINT_H) +#include "sqlite3ext.h" +#endif +SQLITE_EXTENSION_INIT1 +#include +#include + +/* Columns available in this virtual table */ +#define BINFO_COLUMN_TYPE 0 +#define BINFO_COLUMN_NAME 1 +#define BINFO_COLUMN_TBL_NAME 2 +#define BINFO_COLUMN_ROOTPAGE 3 +#define BINFO_COLUMN_SQL 4 +#define BINFO_COLUMN_HASROWID 5 +#define BINFO_COLUMN_NENTRY 6 +#define BINFO_COLUMN_NPAGE 7 +#define BINFO_COLUMN_DEPTH 8 +#define BINFO_COLUMN_SZPAGE 9 +#define BINFO_COLUMN_SCHEMA 10 + +/* Forward declarations */ +typedef struct BinfoTable BinfoTable; +typedef struct BinfoCursor BinfoCursor; + +/* A cursor for the sqlite_btreeinfo table */ +struct BinfoCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_stmt *pStmt; /* Query against sqlite_master */ + int rc; /* Result of previous sqlite_step() call */ + int hasRowid; /* hasRowid value. Negative if unknown. */ + sqlite3_int64 nEntry; /* nEntry value */ + int nPage; /* nPage value */ + int depth; /* depth value */ + int szPage; /* size of a btree page. 0 if unknown */ + char *zSchema; /* Schema being interrogated */ +}; + +/* The sqlite_btreeinfo table */ +struct BinfoTable { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The databse connection */ +}; + +/* +** Connect to the sqlite_btreeinfo virtual table. +*/ +static int binfoConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + BinfoTable *pTab = 0; + int rc = SQLITE_OK; + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(\n" + " type TEXT,\n" + " name TEXT,\n" + " tbl_name TEXT,\n" + " rootpage INT,\n" + " sql TEXT,\n" + " hasRowid BOOLEAN,\n" + " nEntry INT,\n" + " nPage INT,\n" + " depth INT,\n" + " szPage INT,\n" + " zSchema TEXT HIDDEN\n" + ")"); + if( rc==SQLITE_OK ){ + pTab = (BinfoTable *)sqlite3_malloc64(sizeof(BinfoTable)); + if( pTab==0 ) rc = SQLITE_NOMEM; + } + assert( rc==SQLITE_OK || pTab==0 ); + if( pTab ){ + pTab->db = db; + } + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Disconnect from or destroy a btreeinfo virtual table. +*/ +static int binfoDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** idxNum: +** +** 0 Use "main" for the schema +** 1 Schema identified by parameter ?1 +*/ +static int binfoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int i; + pIdxInfo->estimatedCost = 10000.0; /* Cost estimate */ + pIdxInfo->estimatedRows = 100; + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + if( p->usable + && p->iColumn==BINFO_COLUMN_SCHEMA + && p->op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + pIdxInfo->estimatedCost = 1000.0; + pIdxInfo->idxNum = 1; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + break; + } + } + return SQLITE_OK; +} + +/* +** Open a new btreeinfo cursor. +*/ +static int binfoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + BinfoCursor *pCsr; + + pCsr = (BinfoCursor *)sqlite3_malloc64(sizeof(BinfoCursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + }else{ + memset(pCsr, 0, sizeof(BinfoCursor)); + pCsr->base.pVtab = pVTab; + } + + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Close a btreeinfo cursor. +*/ +static int binfoClose(sqlite3_vtab_cursor *pCursor){ + BinfoCursor *pCsr = (BinfoCursor *)pCursor; + sqlite3_finalize(pCsr->pStmt); + sqlite3_free(pCsr->zSchema); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Move a btreeinfo cursor to the next entry in the file. +*/ +static int binfoNext(sqlite3_vtab_cursor *pCursor){ + BinfoCursor *pCsr = (BinfoCursor *)pCursor; + pCsr->rc = sqlite3_step(pCsr->pStmt); + pCsr->hasRowid = -1; + return pCsr->rc==SQLITE_ERROR ? SQLITE_ERROR : SQLITE_OK; +} + +/* We have reached EOF if previous sqlite3_step() returned +** anything other than SQLITE_ROW; +*/ +static int binfoEof(sqlite3_vtab_cursor *pCursor){ + BinfoCursor *pCsr = (BinfoCursor *)pCursor; + return pCsr->rc!=SQLITE_ROW; +} + +/* Position a cursor back to the beginning. +*/ +static int binfoFilter( + sqlite3_vtab_cursor *pCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + BinfoCursor *pCsr = (BinfoCursor *)pCursor; + BinfoTable *pTab = (BinfoTable *)pCursor->pVtab; + char *zSql; + int rc; + + sqlite3_free(pCsr->zSchema); + if( idxNum==1 && sqlite3_value_type(argv[0])!=SQLITE_NULL ){ + pCsr->zSchema = sqlite3_mprintf("%s", sqlite3_value_text(argv[0])); + }else{ + pCsr->zSchema = sqlite3_mprintf("main"); + } + zSql = sqlite3_mprintf( + "SELECT 0, 'table','sqlite_master','sqlite_master',1,NULL " + "UNION ALL " + "SELECT rowid, type, name, tbl_name, rootpage, sql" + " FROM \"%w\".sqlite_master WHERE rootpage>=1", + pCsr->zSchema); + sqlite3_finalize(pCsr->pStmt); + pCsr->pStmt = 0; + pCsr->hasRowid = -1; + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); + if( rc==SQLITE_OK ){ + rc = binfoNext(pCursor); + } + return rc; +} + +/* Decode big-endian integers */ +static unsigned int get_uint16(unsigned char *a){ + return (a[0]<<8)|a[1]; +} +static unsigned int get_uint32(unsigned char *a){ + return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|a[3]; +} + +/* Examine the b-tree rooted at pgno and estimate its size. +** Return non-zero if anything goes wrong. +*/ +static int binfoCompute(sqlite3 *db, int pgno, BinfoCursor *pCsr){ + sqlite3_int64 nEntry = 1; + int nPage = 1; + unsigned char *aData; + sqlite3_stmt *pStmt = 0; + int rc = SQLITE_OK; + int pgsz = 0; + int nCell; + int iCell; + + rc = sqlite3_prepare_v2(db, + "SELECT data FROM sqlite_dbpage('main') WHERE pgno=?1", -1, + &pStmt, 0); + if( rc ) return rc; + pCsr->depth = 1; + while(1){ + sqlite3_bind_int(pStmt, 1, pgno); + rc = sqlite3_step(pStmt); + if( rc!=SQLITE_ROW ){ + rc = SQLITE_ERROR; + break; + } + pCsr->szPage = pgsz = sqlite3_column_bytes(pStmt, 0); + aData = (unsigned char*)sqlite3_column_blob(pStmt, 0); + if( aData==0 ){ + rc = SQLITE_NOMEM; + break; + } + if( pgno==1 ){ + aData += 100; + pgsz -= 100; + } + pCsr->hasRowid = aData[0]!=2 && aData[0]!=10; + nCell = get_uint16(aData+3); + nEntry *= (nCell+1); + if( aData[0]==10 || aData[0]==13 ) break; + nPage *= (nCell+1); + if( nCell<=1 ){ + pgno = get_uint32(aData+8); + }else{ + iCell = get_uint16(aData+12+2*(nCell/2)); + if( pgno==1 ) iCell -= 100; + if( iCell<=12 || iCell>=pgsz-4 ){ + rc = SQLITE_CORRUPT; + break; + } + pgno = get_uint32(aData+iCell); + } + pCsr->depth++; + sqlite3_reset(pStmt); + } + sqlite3_finalize(pStmt); + pCsr->nPage = nPage; + pCsr->nEntry = nEntry; + if( rc==SQLITE_ROW ) rc = SQLITE_OK; + return rc; +} + +/* Return a column for the sqlite_btreeinfo table */ +static int binfoColumn( + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, + int i +){ + BinfoCursor *pCsr = (BinfoCursor *)pCursor; + if( i>=BINFO_COLUMN_HASROWID && i<=BINFO_COLUMN_SZPAGE && pCsr->hasRowid<0 ){ + int pgno = sqlite3_column_int(pCsr->pStmt, BINFO_COLUMN_ROOTPAGE+1); + sqlite3 *db = sqlite3_context_db_handle(ctx); + int rc = binfoCompute(db, pgno, pCsr); + if( rc ){ + pCursor->pVtab->zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + return SQLITE_ERROR; + } + } + switch( i ){ + case BINFO_COLUMN_NAME: + case BINFO_COLUMN_TYPE: + case BINFO_COLUMN_TBL_NAME: + case BINFO_COLUMN_ROOTPAGE: + case BINFO_COLUMN_SQL: { + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, i+1)); + break; + } + case BINFO_COLUMN_HASROWID: { + sqlite3_result_int(ctx, pCsr->hasRowid); + break; + } + case BINFO_COLUMN_NENTRY: { + sqlite3_result_int64(ctx, pCsr->nEntry); + break; + } + case BINFO_COLUMN_NPAGE: { + sqlite3_result_int(ctx, pCsr->nPage); + break; + } + case BINFO_COLUMN_DEPTH: { + sqlite3_result_int(ctx, pCsr->depth); + break; + } + case BINFO_COLUMN_SCHEMA: { + sqlite3_result_text(ctx, pCsr->zSchema, -1, SQLITE_STATIC); + break; + } + } + return SQLITE_OK; +} + +/* Return the ROWID for the sqlite_btreeinfo table */ +static int binfoRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + BinfoCursor *pCsr = (BinfoCursor *)pCursor; + *pRowid = sqlite3_column_int64(pCsr->pStmt, 0); + return SQLITE_OK; +} + +/* +** Invoke this routine to register the "sqlite_btreeinfo" virtual table module +*/ +int sqlite3BinfoRegister(sqlite3 *db){ + static sqlite3_module binfo_module = { + 0, /* iVersion */ + 0, /* xCreate */ + binfoConnect, /* xConnect */ + binfoBestIndex, /* xBestIndex */ + binfoDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + binfoOpen, /* xOpen - open a cursor */ + binfoClose, /* xClose - close a cursor */ + binfoFilter, /* xFilter - configure scan constraints */ + binfoNext, /* xNext - advance a cursor */ + binfoEof, /* xEof - check for end of scan */ + binfoColumn, /* xColumn - read data */ + binfoRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + }; + return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_btreeinfo_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi); + return sqlite3BinfoRegister(db); +} diff --git a/ext/misc/closure.c b/ext/misc/closure.c index 510c46ec90..74bffc7708 100644 --- a/ext/misc/closure.c +++ b/ext/misc/closure.c @@ -826,17 +826,12 @@ static int closureBestIndex( int iPlan = 0; int i; int idx = 1; - int seenMatch = 0; const struct sqlite3_index_constraint *pConstraint; closure_vtab *pVtab = (closure_vtab*)pTab; double rCost = 10000000.0; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ - if( pConstraint->iColumn==CLOSURE_COL_ROOT - && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ - seenMatch = 1; - } if( pConstraint->usable==0 ) continue; if( (iPlan & 1)==0 && pConstraint->iColumn==CLOSURE_COL_ROOT @@ -893,6 +888,18 @@ static int closureBestIndex( ** or else the result is an empty set. */ iPlan = 0; } + if( (iPlan&1)==0 ){ + /* If there is no usable "root=?" term, then set the index-type to 0. + ** Also clear any argvIndex variables already set. This is necessary + ** to prevent the core from throwing an "xBestIndex malfunction error" + ** error (because the argvIndex values are not contiguously assigned + ** starting from 1). */ + rCost *= 1e30; + for(i=0; inConstraint; i++, pConstraint++){ + pIdxInfo->aConstraintUsage[i].argvIndex = 0; + } + iPlan = 0; + } pIdxInfo->idxNum = iPlan; if( pIdxInfo->nOrderBy==1 && pIdxInfo->aOrderBy[0].iColumn==CLOSURE_COL_ID @@ -900,7 +907,6 @@ static int closureBestIndex( ){ pIdxInfo->orderByConsumed = 1; } - if( seenMatch && (iPlan&1)==0 ) rCost *= 1e30; pIdxInfo->estimatedCost = rCost; return SQLITE_OK; diff --git a/ext/misc/completion.c b/ext/misc/completion.c index 79f889abf1..4a4b918a37 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -62,6 +62,7 @@ struct completion_cursor { char *zPrefix; /* The prefix for the word we want to complete */ char *zLine; /* The whole that we want to complete */ const char *zCurrentRow; /* Current output row */ + int szRow; /* Length of the zCurrentRow string */ sqlite3_stmt *pStmt; /* Current statement */ sqlite3_int64 iRowid; /* The rowid */ int ePhase; /* Current phase */ @@ -78,7 +79,7 @@ struct completion_cursor { #define COMPLETION_INDEXES 5 #define COMPLETION_TRIGGERS 6 #define COMPLETION_DATABASES 7 -#define COMPLETION_TABLES 8 +#define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */ #define COMPLETION_COLUMNS 9 #define COMPLETION_MODULES 10 #define COMPLETION_EOF 11 @@ -174,32 +175,6 @@ static int completionClose(sqlite3_vtab_cursor *cur){ return SQLITE_OK; } -/* -** All SQL keywords understood by SQLite -*/ -static const char *completionKwrds[] = { - "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", - "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", - "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", - "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", - "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", - "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", - "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", - "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", - "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", - "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", - "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", - "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", - "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", - "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", - "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", - "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", - "WITH", "WITHOUT", -}; -#define completionKwCount \ - (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0])) - /* ** Advance a completion_cursor to its next row of output. ** @@ -222,11 +197,11 @@ static int completionNext(sqlite3_vtab_cursor *cur){ while( pCur->ePhase!=COMPLETION_EOF ){ switch( pCur->ePhase ){ case COMPLETION_KEYWORDS: { - if( pCur->j >= completionKwCount ){ + if( pCur->j >= sqlite3_keyword_count() ){ pCur->zCurrentRow = 0; pCur->ePhase = COMPLETION_DATABASES; }else{ - pCur->zCurrentRow = completionKwrds[pCur->j++]; + sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow); } iCol = -1; break; @@ -250,8 +225,7 @@ static int completionNext(sqlite3_vtab_cursor *cur){ const char *zDb = (const char*)sqlite3_column_text(pS2, 1); zSql = sqlite3_mprintf( "%z%s" - "SELECT name FROM \"%w\".sqlite_master" - " WHERE type='table'", + "SELECT name FROM \"%w\".sqlite_master", zSql, zSep, zDb ); if( zSql==0 ) return SQLITE_NOMEM; @@ -299,6 +273,7 @@ static int completionNext(sqlite3_vtab_cursor *cur){ if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){ /* Extract the next row of content */ pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol); + pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol); }else{ /* When all rows are finished, advance to the next phase */ sqlite3_finalize(pCur->pStmt); @@ -308,7 +283,9 @@ static int completionNext(sqlite3_vtab_cursor *cur){ } } if( pCur->nPrefix==0 ) break; - if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){ + if( pCur->nPrefix<=pCur->szRow + && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 + ){ break; } } @@ -328,7 +305,7 @@ static int completionColumn( completion_cursor *pCur = (completion_cursor*)cur; switch( i ){ case COMPLETION_COLUMN_CANDIDATE: { - sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT); break; } case COMPLETION_COLUMN_PREFIX: { @@ -388,7 +365,7 @@ static int completionFilter( pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); if( pCur->zPrefix==0 ) return SQLITE_NOMEM; } - iArg++; + iArg = 1; } if( idxNum & 2 ){ pCur->nLine = sqlite3_value_bytes(argv[iArg]); @@ -396,7 +373,6 @@ static int completionFilter( pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); if( pCur->zLine==0 ) return SQLITE_NOMEM; } - iArg++; } if( pCur->zLine!=0 && pCur->zPrefix==0 ){ int i = pCur->nLine; diff --git a/ext/misc/compress.c b/ext/misc/compress.c index bf38d4c93c..6e7d8b6148 100644 --- a/ext/misc/compress.c +++ b/ext/misc/compress.c @@ -27,6 +27,21 @@ SQLITE_EXTENSION_INIT1 ** seven bits per integer stored in the lower seven bits of each byte. ** More significant bits occur first. The most significant bit (0x80) ** is a flag to indicate the end of the integer. +** +** This function, SQLAR, and ZIP all use the same "deflate" compression +** algorithm, but each is subtly different: +** +** * ZIP uses raw deflate. +** +** * SQLAR uses the "zlib format" which is raw deflate with a two-byte +** algorithm-identification header and a four-byte checksum at the end. +** +** * This utility uses the "zlib format" like SQLAR, but adds the variable- +** length integer uncompressed size value at the beginning. +** +** This function might be extended in the future to support compression +** formats other than deflate, by providing a different algorithm-id +** mark following the variable-length integer size parameter. */ static void compressFunc( sqlite3_context *context, diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 1eafc3a414..ec90f96f28 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -78,7 +78,7 @@ struct CsvReader { int nAlloc; /* Space allocated for z[] */ int nLine; /* Current line number */ int bNotFirst; /* True if prior text has been seen */ - char cTerm; /* Character that terminated the most recent field */ + int cTerm; /* Character that terminated the most recent field */ size_t iIn; /* Next unread character in the input buffer */ size_t nIn; /* Number of characters in the input buffer */ char *zIn; /* The input buffer */ @@ -132,6 +132,7 @@ static int csv_reader_open( } p->in = fopen(zFilename, "rb"); if( p->in==0 ){ + sqlite3_free(p->zIn); csv_reader_reset(p); csv_errmsg(p, "cannot open '%s' for reading", zFilename); return 1; @@ -166,7 +167,7 @@ static int csv_getc(CsvReader *p){ if( p->in!=0 ) return csv_getc_refill(p); return EOF; } - return p->zIn[p->iIn++]; + return ((unsigned char*)p->zIn)[p->iIn++]; } /* Increase the size of p->z and append character c to the end. @@ -204,7 +205,8 @@ static int csv_append(CsvReader *p, char c){ ** + Store the character that terminates the field in p->cTerm. Store ** EOF on end-of-file. ** -** Return "" at EOF. Return 0 on an OOM error. +** Return 0 at EOF or on OOM. On EOF, the p->cTerm character will have +** been set to EOF. */ static char *csv_read_one_field(CsvReader *p){ int c; @@ -212,7 +214,7 @@ static char *csv_read_one_field(CsvReader *p){ c = csv_getc(p); if( c==EOF ){ p->cTerm = EOF; - return ""; + return 0; } if( c=='"' ){ int pc, ppc; @@ -543,8 +545,7 @@ static int csvtabConnect( pNew->nCol = nCol; }else{ do{ - const char *z = csv_read_one_field(&sRdr); - if( z==0 ) goto csvtab_connect_oom; + csv_read_one_field(&sRdr); pNew->nCol++; }while( sRdr.cTerm==',' ); } @@ -662,7 +663,6 @@ static int csvtabNext(sqlite3_vtab_cursor *cur){ do{ z = csv_read_one_field(&pCur->rdr); if( z==0 ){ - csv_xfer_error(pTab, &pCur->rdr); break; } if( inCol ){ diff --git a/ext/misc/dbdump.c b/ext/misc/dbdump.c index 90c2dd4c44..0b4b4bfafa 100644 --- a/ext/misc/dbdump.c +++ b/ext/misc/dbdump.c @@ -141,45 +141,12 @@ static void appendText(DText *p, char const *zAppend, char quote){ ** Return '"' if quoting is required. Return 0 if no quoting is required. */ static char quoteChar(const char *zName){ - /* All SQLite keywords, in alphabetical order */ - static const char *azKeywords[] = { - "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", - "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", - "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", - "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", - "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", - "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", - "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", - "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", - "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", - "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", - "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", - "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", - "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", - "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", - "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", - "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", - "WITH", "WITHOUT", - }; - int i, lwr, upr, mid, c; + int i; if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; for(i=0; zName[i]; i++){ if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; } - lwr = 0; - upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; - while( lwr<=upr ){ - mid = (lwr+upr)/2; - c = sqlite3_stricmp(azKeywords[mid], zName); - if( c==0 ) return '"'; - if( c<0 ){ - lwr = mid+1; - }else{ - upr = mid-1; - } - } - return 0; + return sqlite3_keyword_check(zName, i) ? '"' : 0; } @@ -293,7 +260,6 @@ static char **tableColumnList(DState *p, const char *zTab){ ** ordinary column in the table. Verify that azRowid[j] is a valid ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID ** tables will fail this last check */ - int rc; rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; break; @@ -455,12 +421,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ if( strcmp(zType, "table")==0 ){ DText sSelect; DText sTable; - char **azCol; + char **azTCol; int i; int nCol; - azCol = tableColumnList(p, zTable); - if( azCol==0 ) return 0; + azTCol = tableColumnList(p, zTable); + if( azTCol==0 ) return 0; initText(&sTable); appendText(&sTable, "INSERT INTO ", 0); @@ -473,12 +439,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" ** instead of the usual "INSERT INTO tab VALUES(...)". */ - if( azCol[0] ){ + if( azTCol[0] ){ appendText(&sTable, "(", 0); - appendText(&sTable, azCol[0], 0); - for(i=1; azCol[i]; i++){ + appendText(&sTable, azTCol[0], 0); + for(i=1; azTCol[i]; i++){ appendText(&sTable, ",", 0); - appendText(&sTable, azCol[i], quoteChar(azCol[i])); + appendText(&sTable, azTCol[i], quoteChar(azTCol[i])); } appendText(&sTable, ")", 0); } @@ -487,19 +453,19 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ /* Build an appropriate SELECT statement */ initText(&sSelect); appendText(&sSelect, "SELECT ", 0); - if( azCol[0] ){ - appendText(&sSelect, azCol[0], 0); + if( azTCol[0] ){ + appendText(&sSelect, azTCol[0], 0); appendText(&sSelect, ",", 0); } - for(i=1; azCol[i]; i++){ - appendText(&sSelect, azCol[i], quoteChar(azCol[i])); - if( azCol[i+1] ){ + for(i=1; azTCol[i]; i++){ + appendText(&sSelect, azTCol[i], quoteChar(azTCol[i])); + if( azTCol[i+1] ){ appendText(&sSelect, ",", 0); } } nCol = i; - if( azCol[0]==0 ) nCol--; - freeColumnList(azCol); + if( azTCol[0]==0 ) nCol--; + freeColumnList(azTCol); appendText(&sSelect, " FROM ", 0); appendText(&sSelect, zTable, quoteChar(zTable)); @@ -519,7 +485,15 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ } case SQLITE_FLOAT: { double r = sqlite3_column_double(pStmt,i); - output_formatted(p, "%!.20g", r); + sqlite3_uint64 ur; + memcpy(&ur,&r,sizeof(r)); + if( ur==0x7ff0000000000000LL ){ + p->xCallback("1e999", p->pArg); + }else if( ur==0xfff0000000000000LL ){ + p->xCallback("-1e999", p->pArg); + }else{ + output_formatted(p, "%!.20g", r); + } break; } case SQLITE_NULL: { diff --git a/ext/misc/eval.c b/ext/misc/eval.c index 71b6b69f20..e90bfc0100 100644 --- a/ext/misc/eval.c +++ b/ext/misc/eval.c @@ -34,6 +34,7 @@ struct EvalResult { static int callback(void *pCtx, int argc, char **argv, char **colnames){ struct EvalResult *p = (struct EvalResult*)pCtx; int i; + if( argv==0 ) return 0; for(i=0; i +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* explain_vtab is a subclass of sqlite3_vtab which will +** serve as the underlying representation of a explain virtual table +*/ +typedef struct explain_vtab explain_vtab; +struct explain_vtab { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this explain vtab */ +}; + +/* explain_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result from an EXPLAIN operation. +*/ +typedef struct explain_cursor explain_cursor; +struct explain_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this cursor */ + char *zSql; /* Value for the EXPLN_COLUMN_SQL column */ + sqlite3_stmt *pExplain; /* Statement being explained */ + int rc; /* Result of last sqlite3_step() on pExplain */ +}; + +/* +** The explainConnect() method is invoked to create a new +** explain_vtab that describes the explain virtual table. +** +** Think of this routine as the constructor for explain_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the explain_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against explain will look like. +*/ +static int explainConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + explain_vtab *pNew; + int rc; + +/* Column numbers */ +#define EXPLN_COLUMN_ADDR 0 /* Instruction address */ +#define EXPLN_COLUMN_OPCODE 1 /* Opcode */ +#define EXPLN_COLUMN_P1 2 /* Operand 1 */ +#define EXPLN_COLUMN_P2 3 /* Operand 2 */ +#define EXPLN_COLUMN_P3 4 /* Operand 3 */ +#define EXPLN_COLUMN_P4 5 /* Operand 4 */ +#define EXPLN_COLUMN_P5 6 /* Operand 5 */ +#define EXPLN_COLUMN_COMMENT 7 /* Comment */ +#define EXPLN_COLUMN_SQL 8 /* SQL that is being explained */ + + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(addr,opcode,p1,p2,p3,p4,p5,comment,sql HIDDEN)"); + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + } + return rc; +} + +/* +** This method is the destructor for explain_cursor objects. +*/ +static int explainDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new explain_cursor object. +*/ +static int explainOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + explain_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + pCur->db = ((explain_vtab*)p)->db; + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Destructor for a explain_cursor. +*/ +static int explainClose(sqlite3_vtab_cursor *cur){ + explain_cursor *pCur = (explain_cursor*)cur; + sqlite3_finalize(pCur->pExplain); + sqlite3_free(pCur->zSql); + sqlite3_free(pCur); + return SQLITE_OK; +} + + +/* +** Advance a explain_cursor to its next row of output. +*/ +static int explainNext(sqlite3_vtab_cursor *cur){ + explain_cursor *pCur = (explain_cursor*)cur; + pCur->rc = sqlite3_step(pCur->pExplain); + if( pCur->rc!=SQLITE_DONE && pCur->rc!=SQLITE_ROW ) return pCur->rc; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the explain_cursor +** is currently pointing. +*/ +static int explainColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + explain_cursor *pCur = (explain_cursor*)cur; + if( i==EXPLN_COLUMN_SQL ){ + sqlite3_result_text(ctx, pCur->zSql, -1, SQLITE_TRANSIENT); + }else{ + sqlite3_result_value(ctx, sqlite3_column_value(pCur->pExplain, i)); + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int explainRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + explain_cursor *pCur = (explain_cursor*)cur; + *pRowid = sqlite3_column_int64(pCur->pExplain, 0); + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int explainEof(sqlite3_vtab_cursor *cur){ + explain_cursor *pCur = (explain_cursor*)cur; + return pCur->rc!=SQLITE_ROW; +} + +/* +** This method is called to "rewind" the explain_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to explainColumn() or explainRowid() or +** explainEof(). +** +** The argv[0] is the SQL statement that is to be explained. +*/ +static int explainFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + explain_cursor *pCur = (explain_cursor *)pVtabCursor; + char *zSql = 0; + int rc; + sqlite3_finalize(pCur->pExplain); + pCur->pExplain = 0; + if( sqlite3_value_type(argv[0])!=SQLITE_TEXT ){ + pCur->rc = SQLITE_DONE; + return SQLITE_OK; + } + sqlite3_free(pCur->zSql); + pCur->zSql = sqlite3_mprintf("%s", sqlite3_value_text(argv[0])); + if( pCur->zSql ){ + zSql = sqlite3_mprintf("EXPLAIN %s", pCur->zSql); + } + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pExplain, 0); + sqlite3_free(zSql); + } + if( rc ){ + sqlite3_finalize(pCur->pExplain); + pCur->pExplain = 0; + sqlite3_free(pCur->zSql); + pCur->zSql = 0; + }else{ + pCur->rc = sqlite3_step(pCur->pExplain); + rc = (pCur->rc==SQLITE_DONE || pCur->rc==SQLITE_ROW) ? SQLITE_OK : pCur->rc; + } + return rc; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the explain virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +*/ +static int explainBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; + + pIdxInfo->estimatedCost = (double)1000000; + pIdxInfo->estimatedRows = 500; + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + if( p->usable + && p->iColumn==EXPLN_COLUMN_SQL + && p->op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + pIdxInfo->estimatedCost = 10.0; + pIdxInfo->idxNum = 1; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + break; + } + } + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** explain virtual table. +*/ +static sqlite3_module explainModule = { + 0, /* iVersion */ + 0, /* xCreate */ + explainConnect, /* xConnect */ + explainBestIndex, /* xBestIndex */ + explainDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + explainOpen, /* xOpen - open a cursor */ + explainClose, /* xClose - close a cursor */ + explainFilter, /* xFilter - configure scan constraints */ + explainNext, /* xNext - advance a cursor */ + explainEof, /* xEof - check for end of scan */ + explainColumn, /* xColumn - read data */ + explainRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +int sqlite3ExplainVtabInit(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3_create_module(db, "explain", &explainModule, 0); +#endif + return rc; +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_explain_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3ExplainVtabInit(db); +#endif + return rc; +} diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c index 2c00ad971d..816a353c6e 100644 --- a/ext/misc/fileio.c +++ b/ext/misc/fileio.c @@ -11,11 +11,125 @@ ****************************************************************************** ** ** This SQLite extension implements SQL functions readfile() and -** writefile(). +** writefile(), and eponymous virtual type "fsdir". +** +** WRITEFILE(FILE, DATA [, MODE [, MTIME]]): +** +** If neither of the optional arguments is present, then this UDF +** function writes blob DATA to file FILE. If successful, the number +** of bytes written is returned. If an error occurs, NULL is returned. +** +** If the first option argument - MODE - is present, then it must +** be passed an integer value that corresponds to a POSIX mode +** value (file type + permissions, as returned in the stat.st_mode +** field by the stat() system call). Three types of files may +** be written/created: +** +** regular files: (mode & 0170000)==0100000 +** symbolic links: (mode & 0170000)==0120000 +** directories: (mode & 0170000)==0040000 +** +** For a directory, the DATA is ignored. For a symbolic link, it is +** interpreted as text and used as the target of the link. For a +** regular file, it is interpreted as a blob and written into the +** named file. Regardless of the type of file, its permissions are +** set to (mode & 0777) before returning. +** +** If the optional MTIME argument is present, then it is interpreted +** as an integer - the number of seconds since the unix epoch. The +** modification-time of the target file is set to this value before +** returning. +** +** If three or more arguments are passed to this function and an +** error is encountered, an exception is raised. +** +** READFILE(FILE): +** +** Read and return the contents of file FILE (type blob) from disk. +** +** FSDIR: +** +** Used as follows: +** +** SELECT * FROM fsdir($path [, $dir]); +** +** Parameter $path is an absolute or relative pathname. If the file that it +** refers to does not exist, it is an error. If the path refers to a regular +** file or symbolic link, it returns a single row. Or, if the path refers +** to a directory, it returns one row for the directory, and one row for each +** file within the hierarchy rooted at $path. +** +** Each row has the following columns: +** +** name: Path to file or directory (text value). +** mode: Value of stat.st_mode for directory entry (an integer). +** mtime: Value of stat.st_mtime for directory entry (an integer). +** data: For a regular file, a blob containing the file data. For a +** symlink, a text value containing the text of the link. For a +** directory, NULL. +** +** If a non-NULL value is specified for the optional $dir parameter and +** $path is a relative path, then $path is interpreted relative to $dir. +** And the paths returned in the "name" column of the table are also +** relative to directory $dir. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include +#include +#include + +#include +#include +#include +#if !defined(_WIN32) && !defined(WIN32) +# include +# include +# include +# include +#else +# include "windows.h" +# include +# include +# include "test_windirent.h" +# define dirent DIRENT +# ifndef chmod +# define chmod _chmod +# endif +# ifndef stat +# define stat _stat +# endif +# define mkdir(path,mode) _mkdir(path) +# define lstat(path,buf) stat(path,buf) +#endif +#include +#include + + +#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)" + +/* +** Set the result stored by context ctx to a blob containing the +** contents of file zName. +*/ +static void readFileContents(sqlite3_context *ctx, const char *zName){ + FILE *in; + long nIn; + void *pBuf; + + in = fopen(zName, "rb"); + if( in==0 ) return; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc( nIn ); + if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ + sqlite3_result_blob(ctx, pBuf, nIn, sqlite3_free); + }else{ + sqlite3_free(pBuf); + } + fclose(in); +} /* ** Implementation of the "readfile(X)" SQL function. The entire content @@ -28,58 +142,761 @@ static void readfileFunc( sqlite3_value **argv ){ const char *zName; - FILE *in; - long nIn; - void *pBuf; - (void)(argc); /* Unused parameter */ 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_malloc( nIn ); - if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ - sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); - }else{ - sqlite3_free(pBuf); - } - fclose(in); + readFileContents(context, zName); } /* -** Implementation of the "writefile(X,Y)" SQL function. The argument Y -** is written into file X. The number of bytes written is returned. Or -** NULL is returned if something goes wrong, such as being unable to open -** file X for writing. +** Set the error message contained in context ctx to the results of +** vprintf(zFmt, ...). +*/ +static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ + char *zMsg = 0; + va_list ap; + va_start(ap, zFmt); + zMsg = sqlite3_vmprintf(zFmt, ap); + sqlite3_result_error(ctx, zMsg, -1); + sqlite3_free(zMsg); + va_end(ap); +} + +#if defined(_WIN32) +/* +** This function is designed to convert a Win32 FILETIME structure into the +** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC). +*/ +static sqlite3_uint64 fileTimeToUnixTime( + LPFILETIME pFileTime +){ + SYSTEMTIME epochSystemTime; + ULARGE_INTEGER epochIntervals; + FILETIME epochFileTime; + ULARGE_INTEGER fileIntervals; + + memset(&epochSystemTime, 0, sizeof(SYSTEMTIME)); + epochSystemTime.wYear = 1970; + epochSystemTime.wMonth = 1; + epochSystemTime.wDay = 1; + SystemTimeToFileTime(&epochSystemTime, &epochFileTime); + epochIntervals.LowPart = epochFileTime.dwLowDateTime; + epochIntervals.HighPart = epochFileTime.dwHighDateTime; + + fileIntervals.LowPart = pFileTime->dwLowDateTime; + fileIntervals.HighPart = pFileTime->dwHighDateTime; + + return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000; +} + +/* +** This function attempts to normalize the time values found in the stat() +** buffer to UTC. This is necessary on Win32, where the runtime library +** appears to return these values as local times. +*/ +static void statTimesToUtc( + const char *zPath, + struct stat *pStatBuf +){ + HANDLE hFindFile; + WIN32_FIND_DATAW fd; + LPWSTR zUnicodeName; + extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); + zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); + if( zUnicodeName ){ + memset(&fd, 0, sizeof(WIN32_FIND_DATAW)); + hFindFile = FindFirstFileW(zUnicodeName, &fd); + if( hFindFile!=NULL ){ + pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime); + pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime); + pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime); + FindClose(hFindFile); + } + sqlite3_free(zUnicodeName); + } +} +#endif + +/* +** This function is used in place of stat(). On Windows, special handling +** is required in order for the included time to be returned as UTC. On all +** other systems, this function simply calls stat(). +*/ +static int fileStat( + const char *zPath, + struct stat *pStatBuf +){ +#if defined(_WIN32) + int rc = stat(zPath, pStatBuf); + if( rc==0 ) statTimesToUtc(zPath, pStatBuf); + return rc; +#else + return stat(zPath, pStatBuf); +#endif +} + +/* +** This function is used in place of lstat(). On Windows, special handling +** is required in order for the included time to be returned as UTC. On all +** other systems, this function simply calls lstat(). +*/ +static int fileLinkStat( + const char *zPath, + struct stat *pStatBuf +){ +#if defined(_WIN32) + int rc = lstat(zPath, pStatBuf); + if( rc==0 ) statTimesToUtc(zPath, pStatBuf); + return rc; +#else + return lstat(zPath, pStatBuf); +#endif +} + +/* +** Argument zFile is the name of a file that will be created and/or written +** by SQL function writefile(). This function ensures that the directory +** zFile will be written to exists, creating it if required. The permissions +** for any path components created by this function are set to (mode&0777). +** +** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise, +** SQLITE_OK is returned if the directory is successfully created, or +** SQLITE_ERROR otherwise. +*/ +static int makeDirectory( + const char *zFile, + mode_t mode +){ + char *zCopy = sqlite3_mprintf("%s", zFile); + int rc = SQLITE_OK; + + if( zCopy==0 ){ + rc = SQLITE_NOMEM; + }else{ + int nCopy = (int)strlen(zCopy); + int i = 1; + + while( rc==SQLITE_OK ){ + struct stat sStat; + int rc2; + + for(; zCopy[i]!='/' && i=0 ){ +#if defined(_WIN32) + /* Windows */ + FILETIME lastAccess; + FILETIME lastWrite; + SYSTEMTIME currentTime; + LONGLONG intervals; + HANDLE hFile; + LPWSTR zUnicodeName; + extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); + + GetSystemTime(¤tTime); + SystemTimeToFileTime(¤tTime, &lastAccess); + intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; + lastWrite.dwLowDateTime = (DWORD)intervals; + lastWrite.dwHighDateTime = intervals >> 32; + zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); + if( zUnicodeName==0 ){ + return 1; + } + hFile = CreateFileW( + zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL + ); + sqlite3_free(zUnicodeName); + if( hFile!=INVALID_HANDLE_VALUE ){ + BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite); + CloseHandle(hFile); + return !bResult; + }else{ + return 1; + } +#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */ + /* Recent unix */ + struct timespec times[2]; + times[0].tv_nsec = times[1].tv_nsec = 0; + times[0].tv_sec = time(0); + times[1].tv_sec = mtime; + if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){ + return 1; + } +#else + /* Legacy unix */ + struct timeval times[2]; + times[0].tv_usec = times[1].tv_usec = 0; + times[0].tv_sec = time(0); + times[1].tv_sec = mtime; + if( utimes(zFile, times) ){ + return 1; + } +#endif + } + + return 0; +} + +/* +** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. +** Refer to header comments at the top of this file for details. */ static void writefileFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ - FILE *out; - const char *z; - sqlite3_int64 rc; const char *zFile; + mode_t mode = 0; + int res; + sqlite3_int64 mtime = -1; + + if( argc<2 || argc>4 ){ + sqlite3_result_error(context, + "wrong number of arguments to function writefile()", -1 + ); + return; + } - (void)(argc); /* Unused parameter */ zFile = (const char*)sqlite3_value_text(argv[0]); if( zFile==0 ) return; - out = fopen(zFile, "wb"); - if( out==0 ) return; - z = (const char*)sqlite3_value_blob(argv[1]); - if( z==0 ){ - rc = 0; - }else{ - rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); + if( argc>=3 ){ + mode = (mode_t)sqlite3_value_int(argv[2]); + } + if( argc==4 ){ + mtime = sqlite3_value_int64(argv[3]); + } + + res = writeFile(context, zFile, argv[1], mode, mtime); + if( res==1 && errno==ENOENT ){ + if( makeDirectory(zFile, mode)==SQLITE_OK ){ + res = writeFile(context, zFile, argv[1], mode, mtime); + } + } + + if( argc>2 && res!=0 ){ + if( S_ISLNK(mode) ){ + ctxErrorMsg(context, "failed to create symlink: %s", zFile); + }else if( S_ISDIR(mode) ){ + ctxErrorMsg(context, "failed to create directory: %s", zFile); + }else{ + ctxErrorMsg(context, "failed to write file: %s", zFile); + } } - fclose(out); - sqlite3_result_int64(context, rc); } +/* +** SQL function: lsmode(MODE) +** +** Given a numberic st_mode from stat(), convert it into a human-readable +** text string in the style of "ls -l". +*/ +static void lsModeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + int iMode = sqlite3_value_int(argv[0]); + char z[16]; + (void)argc; + if( S_ISLNK(iMode) ){ + z[0] = 'l'; + }else if( S_ISREG(iMode) ){ + z[0] = '-'; + }else if( S_ISDIR(iMode) ){ + z[0] = 'd'; + }else{ + z[0] = '?'; + } + for(i=0; i<3; i++){ + int m = (iMode >> ((2-i)*3)); + char *a = &z[1 + i*3]; + a[0] = (m & 0x4) ? 'r' : '-'; + a[1] = (m & 0x2) ? 'w' : '-'; + a[2] = (m & 0x1) ? 'x' : '-'; + } + z[10] = '\0'; + sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); +} + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* +** Cursor type for recursively iterating through a directory structure. +*/ +typedef struct fsdir_cursor fsdir_cursor; +typedef struct FsdirLevel FsdirLevel; + +struct FsdirLevel { + DIR *pDir; /* From opendir() */ + char *zDir; /* Name of directory (nul-terminated) */ +}; + +struct fsdir_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + + int nLvl; /* Number of entries in aLvl[] array */ + int iLvl; /* Index of current entry */ + FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ + + const char *zBase; + int nBase; + + struct stat sStat; /* Current lstat() results */ + char *zPath; /* Path to current entry */ + sqlite3_int64 iRowid; /* Current rowid */ +}; + +typedef struct fsdir_tab fsdir_tab; +struct fsdir_tab { + sqlite3_vtab base; /* Base class - must be first */ +}; + +/* +** Construct a new fsdir virtual table object. +*/ +static int fsdirConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + fsdir_tab *pNew = 0; + int rc; + (void)pAux; + (void)argc; + (void)argv; + (void)pzErr; + rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA); + if( rc==SQLITE_OK ){ + pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + *ppVtab = (sqlite3_vtab*)pNew; + return rc; +} + +/* +** This method is the destructor for fsdir vtab objects. +*/ +static int fsdirDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new fsdir_cursor object. +*/ +static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + fsdir_cursor *pCur; + (void)p; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + pCur->iLvl = -1; + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Reset a cursor back to the state it was in when first returned +** by fsdirOpen(). +*/ +static void fsdirResetCursor(fsdir_cursor *pCur){ + int i; + for(i=0; i<=pCur->iLvl; i++){ + FsdirLevel *pLvl = &pCur->aLvl[i]; + if( pLvl->pDir ) closedir(pLvl->pDir); + sqlite3_free(pLvl->zDir); + } + sqlite3_free(pCur->zPath); + sqlite3_free(pCur->aLvl); + pCur->aLvl = 0; + pCur->zPath = 0; + pCur->zBase = 0; + pCur->nBase = 0; + pCur->nLvl = 0; + pCur->iLvl = -1; + pCur->iRowid = 1; +} + +/* +** Destructor for an fsdir_cursor. +*/ +static int fsdirClose(sqlite3_vtab_cursor *cur){ + fsdir_cursor *pCur = (fsdir_cursor*)cur; + + fsdirResetCursor(pCur); + sqlite3_free(pCur); + return SQLITE_OK; +} + +/* +** Set the error message for the virtual table associated with cursor +** pCur to the results of vprintf(zFmt, ...). +*/ +static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){ + va_list ap; + va_start(ap, zFmt); + pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); + va_end(ap); +} + + +/* +** Advance an fsdir_cursor to its next row of output. +*/ +static int fsdirNext(sqlite3_vtab_cursor *cur){ + fsdir_cursor *pCur = (fsdir_cursor*)cur; + mode_t m = pCur->sStat.st_mode; + + pCur->iRowid++; + if( S_ISDIR(m) ){ + /* Descend into this directory */ + int iNew = pCur->iLvl + 1; + FsdirLevel *pLvl; + if( iNew>=pCur->nLvl ){ + int nNew = iNew+1; + int nByte = nNew*sizeof(FsdirLevel); + FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc(pCur->aLvl, nByte); + if( aNew==0 ) return SQLITE_NOMEM; + memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl)); + pCur->aLvl = aNew; + pCur->nLvl = nNew; + } + pCur->iLvl = iNew; + pLvl = &pCur->aLvl[iNew]; + + pLvl->zDir = pCur->zPath; + pCur->zPath = 0; + pLvl->pDir = opendir(pLvl->zDir); + if( pLvl->pDir==0 ){ + fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath); + return SQLITE_ERROR; + } + } + + while( pCur->iLvl>=0 ){ + FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl]; + struct dirent *pEntry = readdir(pLvl->pDir); + if( pEntry ){ + if( pEntry->d_name[0]=='.' ){ + if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue; + if( pEntry->d_name[1]=='\0' ) continue; + } + sqlite3_free(pCur->zPath); + pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name); + if( pCur->zPath==0 ) return SQLITE_NOMEM; + if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ + fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); + return SQLITE_ERROR; + } + return SQLITE_OK; + } + closedir(pLvl->pDir); + sqlite3_free(pLvl->zDir); + pLvl->pDir = 0; + pLvl->zDir = 0; + pCur->iLvl--; + } + + /* EOF */ + sqlite3_free(pCur->zPath); + pCur->zPath = 0; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the series_cursor +** is currently pointing. +*/ +static int fsdirColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + fsdir_cursor *pCur = (fsdir_cursor*)cur; + switch( i ){ + case 0: { /* name */ + sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT); + break; + } + + case 1: /* mode */ + sqlite3_result_int64(ctx, pCur->sStat.st_mode); + break; + + case 2: /* mtime */ + sqlite3_result_int64(ctx, pCur->sStat.st_mtime); + break; + + case 3: { /* data */ + mode_t m = pCur->sStat.st_mode; + if( S_ISDIR(m) ){ + sqlite3_result_null(ctx); +#if !defined(_WIN32) && !defined(WIN32) + }else if( S_ISLNK(m) ){ + char aStatic[64]; + char *aBuf = aStatic; + int nBuf = 64; + int n; + + while( 1 ){ + n = readlink(pCur->zPath, aBuf, nBuf); + if( nzPath); + } + } + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** first row returned is assigned rowid value 1, and each subsequent +** row a value 1 more than that of the previous. +*/ +static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + fsdir_cursor *pCur = (fsdir_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int fsdirEof(sqlite3_vtab_cursor *cur){ + fsdir_cursor *pCur = (fsdir_cursor*)cur; + return (pCur->zPath==0); +} + +/* +** xFilter callback. +*/ +static int fsdirFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + const char *zDir = 0; + fsdir_cursor *pCur = (fsdir_cursor*)cur; + (void)idxStr; + fsdirResetCursor(pCur); + + if( idxNum==0 ){ + fsdirSetErrmsg(pCur, "table function fsdir requires an argument"); + return SQLITE_ERROR; + } + + assert( argc==idxNum && (argc==1 || argc==2) ); + zDir = (const char*)sqlite3_value_text(argv[0]); + if( zDir==0 ){ + fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument"); + return SQLITE_ERROR; + } + if( argc==2 ){ + pCur->zBase = (const char*)sqlite3_value_text(argv[1]); + } + if( pCur->zBase ){ + pCur->nBase = (int)strlen(pCur->zBase)+1; + pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir); + }else{ + pCur->zPath = sqlite3_mprintf("%s", zDir); + } + + if( pCur->zPath==0 ){ + return SQLITE_NOMEM; + } + if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ + fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); + return SQLITE_ERROR; + } + + return SQLITE_OK; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the generate_series virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +** +** In this implementation idxNum is used to represent the +** query plan. idxStr is unused. +** +** The query plan is represented by bits in idxNum: +** +** (1) start = $value -- constraint exists +** (2) stop = $value -- constraint exists +** (4) step = $value -- constraint exists +** (8) output in descending order +*/ +static int fsdirBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop over constraints */ + int idx4 = -1; + int idx5 = -1; + const struct sqlite3_index_constraint *pConstraint; + + (void)tab; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pConstraint->iColumn==4 ) idx4 = i; + if( pConstraint->iColumn==5 ) idx5 = i; + } + + if( idx4<0 ){ + pIdxInfo->idxNum = 0; + pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50); + }else{ + pIdxInfo->aConstraintUsage[idx4].omit = 1; + pIdxInfo->aConstraintUsage[idx4].argvIndex = 1; + if( idx5>=0 ){ + pIdxInfo->aConstraintUsage[idx5].omit = 1; + pIdxInfo->aConstraintUsage[idx5].argvIndex = 2; + pIdxInfo->idxNum = 2; + pIdxInfo->estimatedCost = 10.0; + }else{ + pIdxInfo->idxNum = 1; + pIdxInfo->estimatedCost = 100.0; + } + } + + return SQLITE_OK; +} + +/* +** Register the "fsdir" virtual table. +*/ +static int fsdirRegister(sqlite3 *db){ + static sqlite3_module fsdirModule = { + 0, /* iVersion */ + 0, /* xCreate */ + fsdirConnect, /* xConnect */ + fsdirBestIndex, /* xBestIndex */ + fsdirDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + fsdirOpen, /* xOpen - open a cursor */ + fsdirClose, /* xClose - close a cursor */ + fsdirFilter, /* xFilter - configure scan constraints */ + fsdirNext, /* xNext - advance a cursor */ + fsdirEof, /* xEof - check for end of scan */ + fsdirColumn, /* xColumn - read data */ + fsdirRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ + }; + + int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0); + return rc; +} +#else /* SQLITE_OMIT_VIRTUALTABLE */ +# define fsdirRegister(x) SQLITE_OK +#endif #ifdef _WIN32 __declspec(dllexport) @@ -95,8 +912,15 @@ int sqlite3_fileio_init( rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, readfileFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0, writefileFunc, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0, + lsModeFunc, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = fsdirRegister(db); + } return rc; } diff --git a/ext/misc/json1.c b/ext/misc/json1.c index c1d2334a13..85b1143f83 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -172,6 +172,7 @@ struct JsonParse { u8 nErr; /* Number of errors seen */ u16 iDepth; /* Nesting depth */ int nJson; /* Length of the zJson string in bytes */ + u32 iHold; /* Replace cache line with the lowest iHold value */ }; /* @@ -976,7 +977,8 @@ static int jsonParseFindParents(JsonParse *pParse){ /* ** Magic number used for the JSON parse cache in sqlite3_get_auxdata() */ -#define JSON_CACHE_ID (-429938) +#define JSON_CACHE_ID (-429938) /* First cache entry */ +#define JSON_CACHE_SZ 4 /* Max number of cache entries */ /* ** Obtain a complete parse of the JSON found in the first argument @@ -988,16 +990,42 @@ static int jsonParseFindParents(JsonParse *pParse){ */ static JsonParse *jsonParseCached( sqlite3_context *pCtx, - sqlite3_value **argv + sqlite3_value **argv, + sqlite3_context *pErrCtx ){ const char *zJson = (const char*)sqlite3_value_text(argv[0]); int nJson = sqlite3_value_bytes(argv[0]); JsonParse *p; + JsonParse *pMatch = 0; + int iKey; + int iMinKey = 0; + u32 iMinHold = 0xffffffff; + u32 iMaxHold = 0; if( zJson==0 ) return 0; - p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); - if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){ - p->nErr = 0; - return p; /* The cached entry matches, so return it */ + for(iKey=0; iKeynJson==nJson + && memcmp(p->zJson,zJson,nJson)==0 + ){ + p->nErr = 0; + pMatch = p; + }else if( p->iHoldiHold; + iMinKey = iKey; + } + if( p->iHold>iMaxHold ){ + iMaxHold = p->iHold; + } + } + if( pMatch ){ + pMatch->nErr = 0; + pMatch->iHold = iMaxHold+1; + return pMatch; } p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); if( p==0 ){ @@ -1007,13 +1035,15 @@ static JsonParse *jsonParseCached( memset(p, 0, sizeof(*p)); p->zJson = (char*)&p[1]; memcpy((char*)p->zJson, zJson, nJson+1); - if( jsonParse(p, pCtx, p->zJson) ){ + if( jsonParse(p, pErrCtx, p->zJson) ){ sqlite3_free(p); return 0; } p->nJson = nJson; - sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree); - return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); + p->iHold = iMaxHold+1; + sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, + (void(*)(void*))jsonParseFree); + return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); } /* @@ -1386,7 +1416,7 @@ static void jsonArrayLengthFunc( u32 i; JsonNode *pNode; - p = jsonParseCached(ctx, argv); + p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; assert( p->nNode ); if( argc==2 ){ @@ -1427,7 +1457,7 @@ static void jsonExtractFunc( int i; if( argc<2 ) return; - p = jsonParseCached(ctx, argv); + p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; jsonInit(&jx, ctx); jsonAppendChar(&jx, '['); @@ -1734,22 +1764,21 @@ static void jsonTypeFunc( int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *p; /* The parse */ const char *zPath; JsonNode *pNode; - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); + p = jsonParseCached(ctx, argv, ctx); + if( p==0 ) return; if( argc==2 ){ zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(&x, zPath, 0, ctx); + pNode = jsonLookup(p, zPath, 0, ctx); }else{ - pNode = x.aNode; + pNode = p->aNode; } if( pNode ){ sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); } - jsonParseReset(&x); } /* @@ -1763,15 +1792,10 @@ static void jsonValidFunc( int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ - int rc = 0; - + JsonParse *p; /* The parse */ UNUSED_PARAM(argc); - if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){ - rc = 1; - } - jsonParseReset(&x); - sqlite3_result_int(ctx, rc); + p = jsonParseCached(ctx, argv, 0); + sqlite3_result_int(ctx, p!=0); } @@ -1802,7 +1826,7 @@ static void jsonArrayStep( jsonAppendValue(pStr, argv[0]); } } -static void jsonArrayFinal(sqlite3_context *ctx){ +static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ @@ -1811,16 +1835,66 @@ static void jsonArrayFinal(sqlite3_context *ctx){ if( pStr->bErr ){ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); - }else{ - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; } }else{ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); } sqlite3_result_subtype(ctx, JSON_SUBTYPE); } +static void jsonArrayValue(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 0); +} +static void jsonArrayFinal(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 1); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** This method works for both json_group_array() and json_group_object(). +** It works by removing the first element of the group by searching forward +** to the first comma (",") that is not within a string and deleting all +** text through that comma. +*/ +static void jsonGroupInverse( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + int inStr = 0; + char *z; + JsonString *pStr; + UNUSED_PARAM(argc); + UNUSED_PARAM(argv); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); +#ifdef NEVER + /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will + ** always have been called to initalize it */ + if( NEVER(!pStr) ) return; +#endif + z = pStr->zBuf; + for(i=1; z[i]!=',' || inStr; i++){ + assert( inUsed ); + if( z[i]=='"' ){ + inStr = !inStr; + }else if( z[i]=='\\' ){ + i++; + } + } + pStr->nUsed -= i; + memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); +} +#else +# define jsonGroupInverse 0 +#endif + /* ** json_group_obj(NAME,VALUE) @@ -1852,7 +1926,7 @@ static void jsonObjectStep( jsonAppendValue(pStr, argv[1]); } } -static void jsonObjectFinal(sqlite3_context *ctx){ +static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ @@ -1860,16 +1934,26 @@ static void jsonObjectFinal(sqlite3_context *ctx){ if( pStr->bErr ){ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); - }else{ - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; } }else{ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); } sqlite3_result_subtype(ctx, JSON_SUBTYPE); } +static void jsonObjectValue(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 0); +} +static void jsonObjectFinal(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 1); +} + #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -2118,7 +2202,7 @@ static int jsonEachColumn( } if( p->eType==JSON_ARRAY ){ jsonPrintf(30, &x, "[%d]", p->iRowid); - }else{ + }else if( p->eType==JSON_OBJECT ){ jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); } } @@ -2377,9 +2461,12 @@ int sqlite3Json1Init(sqlite3 *db){ int nArg; void (*xStep)(sqlite3_context*,int,sqlite3_value**); void (*xFinal)(sqlite3_context*); + void (*xValue)(sqlite3_context*); } aAgg[] = { - { "json_group_array", 1, jsonArrayStep, jsonArrayFinal }, - { "json_group_object", 2, jsonObjectStep, jsonObjectFinal }, + { "json_group_array", 1, + jsonArrayStep, jsonArrayFinal, jsonArrayValue }, + { "json_group_object", 2, + jsonObjectStep, jsonObjectFinal, jsonObjectValue }, }; #ifndef SQLITE_OMIT_VIRTUALTABLE static const struct { @@ -2396,11 +2483,14 @@ int sqlite3Json1Init(sqlite3 *db){ (void*)&aFunc[i].flag, aFunc[i].xFunc, 0, 0); } +#ifndef SQLITE_OMIT_WINDOWFUNC for(i=0; i +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* memstat_vtab is a subclass of sqlite3_vtab which will +** serve as the underlying representation of a memstat virtual table +*/ +typedef struct memstat_vtab memstat_vtab; +struct memstat_vtab { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this memstat vtab */ +}; + +/* memstat_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct memstat_cursor memstat_cursor; +struct memstat_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this cursor */ + int iRowid; /* Current row in aMemstatColumn[] */ + int iDb; /* Which schema we are looking at */ + int nDb; /* Number of schemas */ + char **azDb; /* Names of all schemas */ + sqlite3_int64 aVal[2]; /* Result values */ +}; + +/* +** The memstatConnect() method is invoked to create a new +** memstat_vtab that describes the memstat virtual table. +** +** Think of this routine as the constructor for memstat_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the memstat_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against memstat will look like. +*/ +static int memstatConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + memstat_vtab *pNew; + int rc; + +/* Column numbers */ +#define MSV_COLUMN_NAME 0 /* Name of quantity being measured */ +#define MSV_COLUMN_SCHEMA 1 /* schema name */ +#define MSV_COLUMN_VALUE 2 /* Current value */ +#define MSV_COLUMN_HIWTR 3 /* Highwater mark */ + + rc = sqlite3_declare_vtab(db,"CREATE TABLE x(name,schema,value,hiwtr)"); + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + } + return rc; +} + +/* +** This method is the destructor for memstat_cursor objects. +*/ +static int memstatDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new memstat_cursor object. +*/ +static int memstatOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + memstat_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + pCur->db = ((memstat_vtab*)p)->db; + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Clear all the schema names from a cursor +*/ +static void memstatClearSchema(memstat_cursor *pCur){ + int i; + if( pCur->azDb==0 ) return; + for(i=0; inDb; i++){ + sqlite3_free(pCur->azDb[i]); + } + sqlite3_free(pCur->azDb); + pCur->azDb = 0; + pCur->nDb = 0; +} + +/* +** Fill in the azDb[] array for the cursor. +*/ +static int memstatFindSchemas(memstat_cursor *pCur){ + sqlite3_stmt *pStmt = 0; + int rc; + if( pCur->nDb ) return SQLITE_OK; + rc = sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pStmt, 0); + if( rc ){ + sqlite3_finalize(pStmt); + return rc; + } + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char **az, *z; + az = sqlite3_realloc(pCur->azDb, sizeof(char*)*(pCur->nDb+1)); + if( az==0 ){ + memstatClearSchema(pCur); + return SQLITE_NOMEM; + } + pCur->azDb = az; + z = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); + if( z==0 ){ + memstatClearSchema(pCur); + return SQLITE_NOMEM; + } + pCur->azDb[pCur->nDb] = z; + pCur->nDb++; + } + sqlite3_finalize(pStmt); + return SQLITE_OK; +} + + +/* +** Destructor for a memstat_cursor. +*/ +static int memstatClose(sqlite3_vtab_cursor *cur){ + memstat_cursor *pCur = (memstat_cursor*)cur; + memstatClearSchema(pCur); + sqlite3_free(cur); + return SQLITE_OK; +} + + +/* +** Allowed values for aMemstatColumn[].eType +*/ +#define MSV_GSTAT 0 /* sqlite3_status64() information */ +#define MSV_DB 1 /* sqlite3_db_status() information */ +#define MSV_ZIPVFS 2 /* ZIPVFS file-control with 64-bit return */ + +/* +** An array of quantities that can be measured and reported by +** this virtual table +*/ +static const struct MemstatColumns { + const char *zName; /* Symbolic name */ + unsigned char eType; /* Type of interface */ + unsigned char mNull; /* Bitmask of which columns are NULL */ + /* 2: dbname, 4: current, 8: hiwtr */ + int eOp; /* Opcode */ +} aMemstatColumn[] = { + {"MEMORY_USED", MSV_GSTAT, 2, SQLITE_STATUS_MEMORY_USED }, + {"MALLOC_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_MALLOC_SIZE }, + {"MALLOC_COUNT", MSV_GSTAT, 2, SQLITE_STATUS_MALLOC_COUNT }, + {"PAGECACHE_USED", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_USED }, + {"PAGECACHE_OVERFLOW", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_OVERFLOW }, + {"PAGECACHE_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_PAGECACHE_SIZE }, + {"PARSER_STACK", MSV_GSTAT, 6, SQLITE_STATUS_PARSER_STACK }, + {"DB_LOOKASIDE_USED", MSV_DB, 2, SQLITE_DBSTATUS_LOOKASIDE_USED }, + {"DB_LOOKASIDE_HIT", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_HIT }, + {"DB_LOOKASIDE_MISS_SIZE", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE}, + {"DB_LOOKASIDE_MISS_FULL", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL}, + {"DB_CACHE_USED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED }, +#if SQLITE_VERSION_NUMBER >= 3140000 + {"DB_CACHE_USED_SHARED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED_SHARED }, +#endif + {"DB_SCHEMA_USED", MSV_DB, 10, SQLITE_DBSTATUS_SCHEMA_USED }, + {"DB_STMT_USED", MSV_DB, 10, SQLITE_DBSTATUS_STMT_USED }, + {"DB_CACHE_HIT", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_HIT }, + {"DB_CACHE_MISS", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_MISS }, + {"DB_CACHE_WRITE", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_WRITE }, +#if SQLITE_VERSION_NUMBER >= 3230000 + {"DB_CACHE_SPILL", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_SPILL }, +#endif + {"DB_DEFERRED_FKS", MSV_DB, 10, SQLITE_DBSTATUS_DEFERRED_FKS }, +#ifdef SQLITE_ENABLE_ZIPVFS + {"ZIPVFS_CACHE_USED", MSV_ZIPVFS, 8, 231454 }, + {"ZIPVFS_CACHE_HIT", MSV_ZIPVFS, 8, 231455 }, + {"ZIPVFS_CACHE_MISS", MSV_ZIPVFS, 8, 231456 }, + {"ZIPVFS_CACHE_WRITE", MSV_ZIPVFS, 8, 231457 }, + {"ZIPVFS_DIRECT_READ", MSV_ZIPVFS, 8, 231458 }, + {"ZIPVFS_DIRECT_BYTES", MSV_ZIPVFS, 8, 231459 }, +#endif /* SQLITE_ENABLE_ZIPVFS */ +}; +#define MSV_NROW (sizeof(aMemstatColumn)/sizeof(aMemstatColumn[0])) + +/* +** Advance a memstat_cursor to its next row of output. +*/ +static int memstatNext(sqlite3_vtab_cursor *cur){ + memstat_cursor *pCur = (memstat_cursor*)cur; + int i; + assert( pCur->iRowid<=MSV_NROW ); + while(1){ + i = (int)pCur->iRowid - 1; + if( (aMemstatColumn[i].mNull & 2)!=0 || (++pCur->iDb)>=pCur->nDb ){ + pCur->iRowid++; + if( pCur->iRowid>MSV_NROW ) return SQLITE_OK; /* End of the table */ + pCur->iDb = 0; + i++; + } + pCur->aVal[0] = 0; + pCur->aVal[1] = 0; + switch( aMemstatColumn[i].eType ){ + case MSV_GSTAT: { + if( sqlite3_libversion_number()>=3010000 ){ + sqlite3_status64(aMemstatColumn[i].eOp, + &pCur->aVal[0], &pCur->aVal[1],0); + }else{ + int xCur, xHiwtr; + sqlite3_status(aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0); + pCur->aVal[0] = xCur; + pCur->aVal[1] = xHiwtr; + } + break; + } + case MSV_DB: { + int xCur, xHiwtr; + sqlite3_db_status(pCur->db, aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0); + pCur->aVal[0] = xCur; + pCur->aVal[1] = xHiwtr; + break; + } + case MSV_ZIPVFS: { + int rc; + rc = sqlite3_file_control(pCur->db, pCur->azDb[pCur->iDb], + aMemstatColumn[i].eOp, (void*)&pCur->aVal[0]); + if( rc!=SQLITE_OK ) continue; + break; + } + } + break; + } + return SQLITE_OK; +} + + +/* +** Return values of columns for the row at which the memstat_cursor +** is currently pointing. +*/ +static int memstatColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int iCol /* Which column to return */ +){ + memstat_cursor *pCur = (memstat_cursor*)cur; + int i; + assert( pCur->iRowid>0 && pCur->iRowid<=MSV_NROW ); + i = (int)pCur->iRowid - 1; + if( (aMemstatColumn[i].mNull & (1<azDb[pCur->iDb], -1, 0); + break; + } + case MSV_COLUMN_VALUE: { + sqlite3_result_int64(ctx, pCur->aVal[0]); + break; + } + case MSV_COLUMN_HIWTR: { + sqlite3_result_int64(ctx, pCur->aVal[1]); + break; + } + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int memstatRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + memstat_cursor *pCur = (memstat_cursor*)cur; + *pRowid = pCur->iRowid*1000 + pCur->iDb; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int memstatEof(sqlite3_vtab_cursor *cur){ + memstat_cursor *pCur = (memstat_cursor*)cur; + return pCur->iRowid>MSV_NROW; +} + +/* +** This method is called to "rewind" the memstat_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to memstatColumn() or memstatRowid() or +** memstatEof(). +*/ +static int memstatFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + memstat_cursor *pCur = (memstat_cursor *)pVtabCursor; + int rc = memstatFindSchemas(pCur); + if( rc ) return rc; + pCur->iRowid = 0; + pCur->iDb = 0; + return memstatNext(pVtabCursor); +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the memstat virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +*/ +static int memstatBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + pIdxInfo->estimatedCost = (double)500; + pIdxInfo->estimatedRows = 500; + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** memstat virtual table. +*/ +static sqlite3_module memstatModule = { + 0, /* iVersion */ + 0, /* xCreate */ + memstatConnect, /* xConnect */ + memstatBestIndex, /* xBestIndex */ + memstatDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + memstatOpen, /* xOpen - open a cursor */ + memstatClose, /* xClose - close a cursor */ + memstatFilter, /* xFilter - configure scan constraints */ + memstatNext, /* xNext - advance a cursor */ + memstatEof, /* xEof - check for end of scan */ + memstatColumn, /* xColumn - read data */ + memstatRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +int sqlite3MemstatVtabInit(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3_create_module(db, "sqlite_memstat", &memstatModule, 0); +#endif + return rc; +} + +#ifndef SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_memstat_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3MemstatVtabInit(db); +#endif + return rc; +} +#endif /* SQLITE_CORE */ +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_MEMSTATVTAB) */ diff --git a/ext/misc/memvfs.c b/ext/misc/memvfs.c index 62a8a033d7..27a61c35e4 100644 --- a/ext/misc/memvfs.c +++ b/ext/misc/memvfs.c @@ -10,23 +10,33 @@ ** ****************************************************************************** ** -** This is an in-memory read-only VFS implementation. The application -** supplies a block of memory which is the database file, and this VFS -** uses that block of memory. +** This is an in-memory VFS implementation. The application supplies +** a chunk of memory to hold the database file. ** -** Because there is no place to store journals and no good way to lock -** the "file", this VFS is read-only. +** Because there is place to store a rollback or wal journal, the database +** must use one of journal_mode=MEMORY or journal_mode=NONE. ** ** USAGE: ** -** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336", &db, -** SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, +** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336&max=65536", &db, +** SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI, ** "memvfs"); ** -** The ptr= and sz= query parameters are required or the open will fail. -** The ptr= parameter gives the memory address of the buffer holding the -** read-only database and sz= gives the size of the database. The parameter -** values may be in hexadecimal or decimal. The filename is ignored. +** These are the query parameters: +** +** ptr= The address of the memory buffer that holds the database. +** +** sz= The current size the database file +** +** maxsz= The maximum size of the database. In other words, the +** amount of space allocated for the ptr= buffer. +** +** freeonclose= If true, then sqlite3_free() is called on the ptr= +** value when the connection closes. +** +** The ptr= and sz= query parameters are required. If maxsz= is omitted, +** then it defaults to the sz= value. Parameter values can be in either +** decimal or hexadecimal. The filename in the URI is ignored. */ #include SQLITE_EXTENSION_INIT1 @@ -49,7 +59,9 @@ typedef struct MemFile MemFile; struct MemFile { sqlite3_file base; /* IO methods */ sqlite3_int64 sz; /* Size of the file */ + sqlite3_int64 szMax; /* Space allocated to aData */ unsigned char *aData; /* content of the file */ + int bFreeOnClose; /* Invoke sqlite3_free() on aData at close */ }; /* @@ -144,6 +156,8 @@ static const sqlite3_io_methods mem_io_methods = { ** to free. */ static int memClose(sqlite3_file *pFile){ + MemFile *p = (MemFile *)pFile; + if( p->bFreeOnClose ) sqlite3_free(p->aData); return SQLITE_OK; } @@ -170,21 +184,34 @@ static int memWrite( int iAmt, sqlite_int64 iOfst ){ - return SQLITE_READONLY; + MemFile *p = (MemFile *)pFile; + if( iOfst+iAmt>p->sz ){ + if( iOfst+iAmt>p->szMax ) return SQLITE_FULL; + if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); + p->sz = iOfst+iAmt; + } + memcpy(p->aData+iOfst, z, iAmt); + return SQLITE_OK; } /* ** Truncate an mem-file. */ static int memTruncate(sqlite3_file *pFile, sqlite_int64 size){ - return SQLITE_READONLY; + MemFile *p = (MemFile *)pFile; + if( size>p->sz ){ + if( size>p->szMax ) return SQLITE_FULL; + memset(p->aData+p->sz, 0, size-p->sz); + } + p->sz = size; + return SQLITE_OK; } /* ** Sync an mem-file. */ static int memSync(sqlite3_file *pFile, int flags){ - return SQLITE_READONLY; + return SQLITE_OK; } /* @@ -200,7 +227,7 @@ static int memFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ ** Lock an mem-file. */ static int memLock(sqlite3_file *pFile, int eLock){ - return SQLITE_READONLY; + return SQLITE_OK; } /* @@ -242,7 +269,10 @@ static int memSectorSize(sqlite3_file *pFile){ ** Return the device characteristic flags supported by an mem-file. */ static int memDeviceCharacteristics(sqlite3_file *pFile){ - return SQLITE_IOCAP_IMMUTABLE; + return SQLITE_IOCAP_ATOMIC | + SQLITE_IOCAP_POWERSAFE_OVERWRITE | + SQLITE_IOCAP_SAFE_APPEND | + SQLITE_IOCAP_SEQUENTIAL; } /* Create a shared memory file mapping */ @@ -253,12 +283,12 @@ static int memShmMap( int bExtend, void volatile **pp ){ - return SQLITE_READONLY; + return SQLITE_IOERR_SHMMAP; } /* Perform locking on a shared-memory segment */ static int memShmLock(sqlite3_file *pFile, int offset, int n, int flags){ - return SQLITE_READONLY; + return SQLITE_IOERR_SHMLOCK; } /* Memory barrier operation on shared memory */ @@ -305,6 +335,9 @@ static int memOpen( if( p->aData==0 ) return SQLITE_CANTOPEN; p->sz = sqlite3_uri_int64(zName,"sz",0); if( p->sz<0 ) return SQLITE_CANTOPEN; + p->szMax = sqlite3_uri_int64(zName,"max",p->sz); + if( p->szMaxsz ) return SQLITE_CANTOPEN; + p->bFreeOnClose = sqlite3_uri_boolean(zName,"freeonclose",0); pFile->pMethods = &mem_io_methods; return SQLITE_OK; } @@ -315,7 +348,7 @@ static int memOpen( ** returning. */ static int memDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ - return SQLITE_READONLY; + return SQLITE_IOERR_DELETE; } /* @@ -328,14 +361,7 @@ static int memAccess( int flags, int *pResOut ){ - /* The spec says there are three possible values for flags. But only - ** two of them are actually used */ - assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); - if( flags==SQLITE_ACCESS_READWRITE ){ - *pResOut = 0; - }else{ - *pResOut = 1; - } + *pResOut = 0; return SQLITE_OK; } @@ -416,31 +442,43 @@ static int memCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ #ifdef MEMVFS_TEST /* -** memload(FILENAME) +** memvfs_from_file(FILENAME, MAXSIZE) ** ** This an SQL function used to help in testing the memvfs VFS. The ** function reads the content of a file into memory and then returns -** a string that gives the locate and size of the in-memory buffer. +** a URI that can be handed to ATTACH to attach the memory buffer as +** a database. Example: +** +** ATTACH memvfs_from_file('test.db',1048576) AS inmem; +** +** The optional MAXSIZE argument gives the size of the memory allocation +** used to hold the database. If omitted, it defaults to the size of the +** file on disk. */ #include -static void memvfsMemloadFunc( +static void memvfsFromFileFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ unsigned char *p; sqlite3_int64 sz; + sqlite3_int64 szMax; FILE *in; const char *zFilename = (const char*)sqlite3_value_text(argv[0]); - char zReturn[100]; + char *zUri; if( zFilename==0 ) return; in = fopen(zFilename, "rb"); if( in==0 ) return; fseek(in, 0, SEEK_END); - sz = ftell(in); + szMax = sz = ftell(in); rewind(in); - p = sqlite3_malloc( sz ); + if( argc>=2 ){ + szMax = sqlite3_value_int64(argv[1]); + if( szMaxzName,"memvfs")!=0 ) return; + rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); + if( rc ) return; + fwrite(p->aData, 1, (size_t)p->sz, out); + fclose(out); +} +#endif /* MEMVFS_TEST */ + +#ifdef MEMVFS_TEST /* Called for each new database connection */ static int memvfsRegister( sqlite3 *db, - const char **pzErrMsg, + char **pzErrMsg, const struct sqlite3_api_routines *pThunk ){ - return sqlite3_create_function(db, "memload", 1, SQLITE_UTF8, 0, - memvfsMemloadFunc, 0, 0); + sqlite3_create_function(db, "memvfs_from_file", 1, SQLITE_UTF8, 0, + memvfsFromFileFunc, 0, 0); + sqlite3_create_function(db, "memvfs_from_file", 2, SQLITE_UTF8, 0, + memvfsFromFileFunc, 0, 0); + sqlite3_create_function(db, "memvfs_to_file", 2, SQLITE_UTF8, 0, + memvfsToFileFunc, 0, 0); + return SQLITE_OK; } #endif /* MEMVFS_TEST */ @@ -485,6 +565,9 @@ int sqlite3_memvfs_init( if( rc==SQLITE_OK ){ rc = sqlite3_auto_extension((void(*)(void))memvfsRegister); } + if( rc==SQLITE_OK ){ + rc = memvfsRegister(db, pzErrMsg, pApi); + } #endif if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; return rc; diff --git a/ext/misc/mmapwarm.c b/ext/misc/mmapwarm.c new file mode 100644 index 0000000000..4e23638a99 --- /dev/null +++ b/ext/misc/mmapwarm.c @@ -0,0 +1,108 @@ +/* +** 2017-09-18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +*/ + +#include "sqlite3.h" + + +/* +** This function is used to touch each page of a mapping of a memory +** mapped SQLite database. Assuming that the system has sufficient free +** memory and supports sufficiently large mappings, this causes the OS +** to cache the entire database in main memory, making subsequent +** database accesses faster. +** +** If the second parameter to this function is not NULL, it is the name of +** the specific database to operate on (i.e. "main" or the name of an +** attached database). +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** It is not considered an error if the file is not memory-mapped, or if +** the mapping does not span the entire file. If an error does occur, a +** transaction may be left open on the database file. +** +** It is illegal to call this function when the database handle has an +** open transaction. SQLITE_MISUSE is returned in this case. +*/ +int sqlite3_mmap_warm(sqlite3 *db, const char *zDb){ + int rc = SQLITE_OK; + char *zSql = 0; + int pgsz = 0; + int nTotal = 0; + + if( 0==sqlite3_get_autocommit(db) ) return SQLITE_MISUSE; + + /* Open a read-only transaction on the file in question */ + zSql = sqlite3_mprintf("BEGIN; SELECT * FROM %s%q%ssqlite_master", + (zDb ? "'" : ""), (zDb ? zDb : ""), (zDb ? "'." : "") + ); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); + + /* Find the SQLite page size of the file */ + if( rc==SQLITE_OK ){ + zSql = sqlite3_mprintf("PRAGMA %s%q%spage_size", + (zDb ? "'" : ""), (zDb ? zDb : ""), (zDb ? "'." : "") + ); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_stmt *pPgsz = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pPgsz, 0); + sqlite3_free(zSql); + if( rc==SQLITE_OK ){ + if( sqlite3_step(pPgsz)==SQLITE_ROW ){ + pgsz = sqlite3_column_int(pPgsz, 0); + } + rc = sqlite3_finalize(pPgsz); + } + if( rc==SQLITE_OK && pgsz==0 ){ + rc = SQLITE_ERROR; + } + } + } + + /* Touch each mmap'd page of the file */ + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_file *pFd = 0; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFd); + if( rc==SQLITE_OK && pFd->pMethods->iVersion>=3 ){ + sqlite3_int64 iPg = 1; + sqlite3_io_methods const *p = pFd->pMethods; + while( 1 ){ + unsigned char *pMap; + rc = p->xFetch(pFd, pgsz*iPg, pgsz, (void**)&pMap); + if( rc!=SQLITE_OK || pMap==0 ) break; + + nTotal += pMap[0]; + nTotal += pMap[pgsz-1]; + + rc = p->xUnfetch(pFd, pgsz*iPg, (void*)pMap); + if( rc!=SQLITE_OK ) break; + iPg++; + } + sqlite3_log(SQLITE_OK, + "sqlite3_mmap_warm_cache: Warmed up %d pages of %s", iPg==1?0:iPg, + sqlite3_db_filename(db, zDb) + ); + } + + rc2 = sqlite3_exec(db, "END", 0, 0, 0); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + diff --git a/ext/misc/normalize.c b/ext/misc/normalize.c new file mode 100644 index 0000000000..5997ec12e2 --- /dev/null +++ b/ext/misc/normalize.c @@ -0,0 +1,707 @@ +/* +** 2018-01-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code to implement the sqlite3_normalize() function. +** +** char *sqlite3_normalize(const char *zSql); +** +** This function takes an SQL string as input and returns a "normalized" +** version of that string in memory obtained from sqlite3_malloc64(). The +** caller is responsible for ensuring that the returned memory is freed. +** +** If a memory allocation error occurs, this routine returns NULL. +** +** The normalization consists of the following transformations: +** +** (1) Convert every literal (string, blob literal, numeric constant, +** or "NULL" constant) into a ? +** +** (2) Remove all superfluous whitespace, including comments. Change +** all required whitespace to a single space character. +** +** (3) Lowercase all ASCII characters. +** +** (4) If an IN or NOT IN operator is followed by a list of 1 or more +** values, convert that list into "(?,?,?)". +** +** The purpose of normalization is two-fold: +** +** (1) Sanitize queries by removing potentially private or sensitive +** information contained in literals. +** +** (2) Identify structurally identical queries by comparing their +** normalized forms. +** +** Command-Line Utility +** -------------------- +** +** This file also contains code for a command-line utility that converts +** SQL queries in text files into their normalized forms. To build the +** command-line program, compile this file with -DSQLITE_NORMALIZE_CLI +** and link it against the SQLite library. +*/ +#include +#include + +/* +** Implementation note: +** +** Much of the tokenizer logic is copied out of the tokenize.c source file +** of SQLite. That logic could be simplified for this particular application, +** but that would impose a risk of introducing subtle errors. It is best to +** keep the code as close to the original as possible. +** +** The tokenize code is in sync with the SQLite core as of 2018-01-08. +** Any future changes to the core tokenizer might require corresponding +** adjustments to the tokenizer logic in this module. +*/ + + +/* Character classes for tokenizing +** +** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented +** using a lookup table, whereas a switch() directly on c uses a binary search. +** The lookup table is much faster. To maximize speed, and to ensure that +** a lookup table is used, all of the classes need to be small integers and +** all of them need to be used within the switch. +*/ +#define CC_X 0 /* The letter 'x', or start of BLOB literal */ +#define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ +#define CC_ID 2 /* unicode characters usable in IDs */ +#define CC_DIGIT 3 /* Digits */ +#define CC_DOLLAR 4 /* '$' */ +#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ +#define CC_VARNUM 6 /* '?'. Numeric SQL variables */ +#define CC_SPACE 7 /* Space characters */ +#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */ +#define CC_QUOTE2 9 /* '['. [...] style quoted ids */ +#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */ +#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */ +#define CC_LT 12 /* '<'. Part of < or <= or <> */ +#define CC_GT 13 /* '>'. Part of > or >= */ +#define CC_EQ 14 /* '='. Part of = or == */ +#define CC_BANG 15 /* '!'. Part of != */ +#define CC_SLASH 16 /* '/'. / or c-style comment */ +#define CC_LP 17 /* '(' */ +#define CC_RP 18 /* ')' */ +#define CC_SEMI 19 /* ';' */ +#define CC_PLUS 20 /* '+' */ +#define CC_STAR 21 /* '*' */ +#define CC_PERCENT 22 /* '%' */ +#define CC_COMMA 23 /* ',' */ +#define CC_AND 24 /* '&' */ +#define CC_TILDA 25 /* '~' */ +#define CC_DOT 26 /* '.' */ +#define CC_ILLEGAL 27 /* Illegal character */ + +static const unsigned char aiClass[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ +/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, +/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, +/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, +/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1, +/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27, +/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +/* An array to map all upper-case characters into their corresponding +** lower-case character. +** +** SQLite only considers US-ASCII (or EBCDIC) characters. We do not +** handle case conversions for the UTF character set since the tables +** involved are nearly as big or bigger than SQLite itself. +*/ +static const unsigned char sqlite3UpperToLower[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 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 +}; + +/* +** The following 256 byte lookup table is used to support SQLites built-in +** equivalents to the following standard library functions: +** +** isspace() 0x01 +** isalpha() 0x02 +** isdigit() 0x04 +** isalnum() 0x06 +** isxdigit() 0x08 +** toupper() 0x20 +** SQLite identifier character 0x40 +** Quote character 0x80 +** +** Bit 0x20 is set if the mapped character requires translation to upper +** case. i.e. if the character is a lower-case ASCII character. +** If x is a lower-case ASCII character, then its upper-case equivalent +** is (x - 0x20). Therefore toupper() can be implemented as: +** +** (x & ~(map[x]&0x20)) +** +** The equivalent of tolower() is implemented using the sqlite3UpperToLower[] +** array. tolower() is used more often than toupper() by SQLite. +** +** Bit 0x40 is set if the character is non-alphanumeric and can be used in an +** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any +** non-ASCII UTF character. Hence the test for whether or not a character is +** part of an identifier is 0x46. +*/ +static const unsigned char sqlite3CtypeMap[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */ + 0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */ + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */ + 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */ + + 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */ + 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ + 0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */ + 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ +}; +#define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20)) +#define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01) +#define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06) +#define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02) +#define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04) +#define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) +#define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) +#define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) + + +/* +** If X is a character that can be used in an identifier then +** IdChar(X) will be true. Otherwise it is false. +** +** For ASCII, any character with the high-order bit set is +** allowed in an identifier. For 7-bit characters, +** sqlite3IsIdChar[X] must be 1. +** +** For EBCDIC, the rules are more complex but have the same +** end result. +** +** Ticket #1066. the SQL standard does not allow '$' in the +** middle of identifiers. But many SQL implementations do. +** SQLite will allow '$' in identifiers for compatibility. +** But the feature is undocumented. +*/ +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) + +/* +** Ignore testcase() macros +*/ +#define testcase(X) + +/* +** Token values +*/ +#define TK_SPACE 0 +#define TK_NAME 1 +#define TK_LITERAL 2 +#define TK_PUNCT 3 +#define TK_ERROR 4 + +#define TK_MINUS TK_PUNCT +#define TK_LP TK_PUNCT +#define TK_RP TK_PUNCT +#define TK_SEMI TK_PUNCT +#define TK_PLUS TK_PUNCT +#define TK_STAR TK_PUNCT +#define TK_SLASH TK_PUNCT +#define TK_REM TK_PUNCT +#define TK_EQ TK_PUNCT +#define TK_LE TK_PUNCT +#define TK_NE TK_PUNCT +#define TK_LSHIFT TK_PUNCT +#define TK_LT TK_PUNCT +#define TK_GE TK_PUNCT +#define TK_RSHIFT TK_PUNCT +#define TK_GT TK_PUNCT +#define TK_GE TK_PUNCT +#define TK_BITOR TK_PUNCT +#define TK_CONCAT TK_PUNCT +#define TK_COMMA TK_PUNCT +#define TK_BITAND TK_PUNCT +#define TK_BITNOT TK_PUNCT +#define TK_STRING TK_LITERAL +#define TK_ID TK_NAME +#define TK_ILLEGAL TK_ERROR +#define TK_DOT TK_PUNCT +#define TK_INTEGER TK_LITERAL +#define TK_FLOAT TK_LITERAL +#define TK_VARIABLE TK_LITERAL +#define TK_BLOB TK_LITERAL + +/* +** Return the length (in bytes) of the token that begins at z[0]. +** Store the token type in *tokenType before returning. +*/ +static int sqlite3GetToken(const unsigned char *z, int *tokenType){ + int i, c; + switch( aiClass[*z] ){ /* Switch on the character-class of the first byte + ** of the token. See the comment on the CC_ defines + ** above. */ + case CC_SPACE: { + for(i=1; sqlite3Isspace(z[i]); i++){} + *tokenType = TK_SPACE; + return i; + } + case CC_MINUS: { + if( z[1]=='-' ){ + for(i=2; (c=z[i])!=0 && c!='\n'; i++){} + *tokenType = TK_SPACE; + return i; + } + *tokenType = TK_MINUS; + return 1; + } + case CC_LP: { + *tokenType = TK_LP; + return 1; + } + case CC_RP: { + *tokenType = TK_RP; + return 1; + } + case CC_SEMI: { + *tokenType = TK_SEMI; + return 1; + } + case CC_PLUS: { + *tokenType = TK_PLUS; + return 1; + } + case CC_STAR: { + *tokenType = TK_STAR; + return 1; + } + case CC_SLASH: { + if( z[1]!='*' || z[2]==0 ){ + *tokenType = TK_SLASH; + return 1; + } + for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} + if( c ) i++; + *tokenType = TK_SPACE; + return i; + } + case CC_PERCENT: { + *tokenType = TK_REM; + return 1; + } + case CC_EQ: { + *tokenType = TK_EQ; + return 1 + (z[1]=='='); + } + case CC_LT: { + if( (c=z[1])=='=' ){ + *tokenType = TK_LE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_NE; + return 2; + }else if( c=='<' ){ + *tokenType = TK_LSHIFT; + return 2; + }else{ + *tokenType = TK_LT; + return 1; + } + } + case CC_GT: { + if( (c=z[1])=='=' ){ + *tokenType = TK_GE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_RSHIFT; + return 2; + }else{ + *tokenType = TK_GT; + return 1; + } + } + case CC_BANG: { + if( z[1]!='=' ){ + *tokenType = TK_ILLEGAL; + return 1; + }else{ + *tokenType = TK_NE; + return 2; + } + } + case CC_PIPE: { + if( z[1]!='|' ){ + *tokenType = TK_BITOR; + return 1; + }else{ + *tokenType = TK_CONCAT; + return 2; + } + } + case CC_COMMA: { + *tokenType = TK_COMMA; + return 1; + } + case CC_AND: { + *tokenType = TK_BITAND; + return 1; + } + case CC_TILDA: { + *tokenType = TK_BITNOT; + return 1; + } + case CC_QUOTE: { + int delim = z[0]; + testcase( delim=='`' ); + testcase( delim=='\'' ); + testcase( delim=='"' ); + for(i=1; (c=z[i])!=0; i++){ + if( c==delim ){ + if( z[i+1]==delim ){ + i++; + }else{ + break; + } + } + } + if( c=='\'' ){ + *tokenType = TK_STRING; + return i+1; + }else if( c!=0 ){ + *tokenType = TK_ID; + return i+1; + }else{ + *tokenType = TK_ILLEGAL; + return i; + } + } + case CC_DOT: { + if( !sqlite3Isdigit(z[1]) ){ + *tokenType = TK_DOT; + return 1; + } + /* If the next character is a digit, this is a floating point + ** number that begins with ".". Fall thru into the next case */ + } + case CC_DIGIT: { + *tokenType = TK_INTEGER; + if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ + for(i=3; sqlite3Isxdigit(z[i]); i++){} + return i; + } + for(i=0; sqlite3Isdigit(z[i]); i++){} + if( z[i]=='.' ){ + i++; + while( sqlite3Isdigit(z[i]) ){ i++; } + *tokenType = TK_FLOAT; + } + if( (z[i]=='e' || z[i]=='E') && + ( sqlite3Isdigit(z[i+1]) + || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) + ) + ){ + i += 2; + while( sqlite3Isdigit(z[i]) ){ i++; } + *tokenType = TK_FLOAT; + } + while( IdChar(z[i]) ){ + *tokenType = TK_ILLEGAL; + i++; + } + return i; + } + case CC_QUOTE2: { + for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} + *tokenType = c==']' ? TK_ID : TK_ILLEGAL; + return i; + } + case CC_VARNUM: { + *tokenType = TK_VARIABLE; + for(i=1; sqlite3Isdigit(z[i]); i++){} + return i; + } + case CC_DOLLAR: + case CC_VARALPHA: { + int n = 0; + testcase( z[0]=='$' ); testcase( z[0]=='@' ); + testcase( z[0]==':' ); testcase( z[0]=='#' ); + *tokenType = TK_VARIABLE; + for(i=1; (c=z[i])!=0; i++){ + if( IdChar(c) ){ + n++; + }else if( c=='(' && n>0 ){ + do{ + i++; + }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' ); + if( c==')' ){ + i++; + }else{ + *tokenType = TK_ILLEGAL; + } + break; + }else if( c==':' && z[i+1]==':' ){ + i++; + }else{ + break; + } + } + if( n==0 ) *tokenType = TK_ILLEGAL; + return i; + } + case CC_KYWD: { + for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} + if( IdChar(z[i]) ){ + /* This token started out using characters that can appear in keywords, + ** but z[i] is a character not allowed within keywords, so this must + ** be an identifier instead */ + i++; + break; + } + *tokenType = TK_ID; + return i; + } + case CC_X: { + testcase( z[0]=='x' ); testcase( z[0]=='X' ); + if( z[1]=='\'' ){ + *tokenType = TK_BLOB; + for(i=2; sqlite3Isxdigit(z[i]); i++){} + if( z[i]!='\'' || i%2 ){ + *tokenType = TK_ILLEGAL; + while( z[i] && z[i]!='\'' ){ i++; } + } + if( z[i] ) i++; + return i; + } + /* If it is not a BLOB literal, then it must be an ID, since no + ** SQL keywords start with the letter 'x'. Fall through */ + } + case CC_ID: { + i = 1; + break; + } + default: { + *tokenType = TK_ILLEGAL; + return 1; + } + } + while( IdChar(z[i]) ){ i++; } + *tokenType = TK_ID; + return i; +} + +char *sqlite3_normalize(const char *zSql){ + char *z; /* The output string */ + sqlite3_int64 nZ; /* Size of the output string in bytes */ + sqlite3_int64 nSql; /* Size of the input string in bytes */ + int i; /* Next character to read from zSql[] */ + int j; /* Next slot to fill in on z[] */ + int tokenType; /* Type of the next token */ + int n; /* Size of the next token */ + int k; /* Loop counter */ + + nSql = strlen(zSql); + nZ = nSql; + z = sqlite3_malloc64( nZ+2 ); + if( z==0 ) return 0; + for(i=j=0; zSql[i]; i += n){ + n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType); + switch( tokenType ){ + case TK_SPACE: { + break; + } + case TK_ERROR: { + sqlite3_free(z); + return 0; + } + case TK_LITERAL: { + z[j++] = '?'; + break; + } + case TK_PUNCT: + case TK_NAME: { + if( n==4 && sqlite3_strnicmp(zSql+i,"NULL",4)==0 ){ + if( (j>=3 && strncmp(z+j-2,"is",2)==0 && !IdChar(z[j-3])) + || (j>=4 && strncmp(z+j-3,"not",3)==0 && !IdChar(z[j-4])) + ){ + /* NULL is a keyword in this case, not a literal value */ + }else{ + /* Here the NULL is a literal value */ + z[j++] = '?'; + break; + } + } + if( j>0 && IdChar(z[j-1]) && IdChar(zSql[i]) ) z[j++] = ' '; + for(k=0; k0 && z[j-1]==' ' ){ j--; } + if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; } + z[j] = 0; + + /* Make a second pass converting "in(...)" where the "..." is not a + ** SELECT statement into "in(?,?,?)" */ + for(i=0; i5 ){ + memmove(z+n+5, z+n+k, j-(n+k)); + } + j = j-k+5; + z[j] = 0; + memcpy(z+n, "?,?,?", 5); + } + return z; +} + +/* +** For testing purposes, or to build a stand-alone SQL normalizer program, +** compile this one source file with the -DSQLITE_NORMALIZE_CLI and link +** it against any SQLite library. The resulting command-line program will +** run sqlite3_normalize() over the text of all files named on the command- +** line and show the result on standard output. +*/ +#ifdef SQLITE_NORMALIZE_CLI +#include +#include + +/* +** Break zIn up into separate SQL statements and run sqlite3_normalize() +** on each one. Print the result of each run. +*/ +static void normalizeFile(char *zIn){ + int i; + if( zIn==0 ) return; + for(i=0; zIn[i]; i++){ + char cSaved; + if( zIn[i]!=';' ) continue; + cSaved = zIn[i+1]; + zIn[i+1] = 0; + if( sqlite3_complete(zIn) ){ + char *zOut = sqlite3_normalize(zIn); + if( zOut ){ + printf("%s\n", zOut); + sqlite3_free(zOut); + }else{ + fprintf(stderr, "ERROR: %s\n", zIn); + } + zIn[i+1] = cSaved; + zIn += i+1; + i = -1; + }else{ + zIn[i+1] = cSaved; + } + } +} + +/* +** The main routine for "sql_normalize". Read files named on the +** command-line and run the text of each through sqlite3_normalize(). +*/ +int main(int argc, char **argv){ + int i; + FILE *in; + char *zBuf = 0; + sqlite3_int64 sz, got; + + for(i=1; ircErr = SQLITE_IOERR; } - if( pgno>p->iLastPage ) p->iLastPage = pgno; + if( (u32)pgno>p->iLastPage ) p->iLastPage = pgno; } /* Prepare a statement against the "db" database. */ @@ -459,7 +459,7 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){ nLocal = K<=X ? K : M; if( pc+nLocal > p->szUsable-4 ){ ln=__LINE__; goto btree_corrupt; } iChild = scrubBackupInt32(&a[pc+nLocal]); - scrubBackupOverflow(p, iChild, P-nLocal); + scrubBackupOverflow(p, iChild, (u32)(P-nLocal)); } /* Walk the right-most tree */ diff --git a/ext/misc/series.c b/ext/misc/series.c index 684995f3b6..3df0a37e6b 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -195,8 +195,9 @@ static int seriesColumn( } /* -** Return the rowid for the current row. In this implementation, the -** rowid is the same as the output value. +** Return the rowid for the current row. In this implementation, the +** first row returned is assigned rowid value 1, and each subsequent +** row a value 1 more than that of the previous. */ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ series_cursor *pCur = (series_cursor*)cur; @@ -269,6 +270,15 @@ static int seriesFilter( }else{ pCur->iStep = 1; } + for(i=0; imnValue = 1; + pCur->mxValue = 0; + break; + } + } if( idxNum & 8 ){ pCur->isDesc = 1; pCur->iValue = pCur->mxValue; diff --git a/ext/misc/sha1.c b/ext/misc/sha1.c index e2843bdefa..886b1db7bd 100644 --- a/ext/misc/sha1.c +++ b/ext/misc/sha1.c @@ -10,7 +10,7 @@ ** ****************************************************************************** ** -** This SQLite extension implements a functions that compute SHA1 hashes. +** This SQLite extension implements functions that compute SHA1 hashes. ** Two SQL functions are implemented: ** ** sha1(X) diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c index 612e395ccb..e35fa49477 100644 --- a/ext/misc/shathree.c +++ b/ext/misc/shathree.c @@ -10,7 +10,7 @@ ** ****************************************************************************** ** -** This SQLite extension implements a functions that compute SHA1 hashes. +** This SQLite extension implements functions that compute SHA3 hashes. ** Two SQL functions are implemented: ** ** sha3(X,SIZE) @@ -78,9 +78,9 @@ struct SHA3Context { */ static void KeccakF1600Step(SHA3Context *p){ int i; - u64 B0, B1, B2, B3, B4; - u64 C0, C1, C2, C3, C4; - u64 D0, D1, D2, D3, D4; + u64 b0, b1, b2, b3, b4; + u64 c0, c1, c2, c3, c4; + u64 d0, d1, d2, d3, d4; static const u64 RC[] = { 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, @@ -95,301 +95,301 @@ static void KeccakF1600Step(SHA3Context *p){ 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL }; -# define A00 (p->u.s[0]) -# define A01 (p->u.s[1]) -# define A02 (p->u.s[2]) -# define A03 (p->u.s[3]) -# define A04 (p->u.s[4]) -# define A10 (p->u.s[5]) -# define A11 (p->u.s[6]) -# define A12 (p->u.s[7]) -# define A13 (p->u.s[8]) -# define A14 (p->u.s[9]) -# define A20 (p->u.s[10]) -# define A21 (p->u.s[11]) -# define A22 (p->u.s[12]) -# define A23 (p->u.s[13]) -# define A24 (p->u.s[14]) -# define A30 (p->u.s[15]) -# define A31 (p->u.s[16]) -# define A32 (p->u.s[17]) -# define A33 (p->u.s[18]) -# define A34 (p->u.s[19]) -# define A40 (p->u.s[20]) -# define A41 (p->u.s[21]) -# define A42 (p->u.s[22]) -# define A43 (p->u.s[23]) -# define A44 (p->u.s[24]) +# define a00 (p->u.s[0]) +# define a01 (p->u.s[1]) +# define a02 (p->u.s[2]) +# define a03 (p->u.s[3]) +# define a04 (p->u.s[4]) +# define a10 (p->u.s[5]) +# define a11 (p->u.s[6]) +# define a12 (p->u.s[7]) +# define a13 (p->u.s[8]) +# define a14 (p->u.s[9]) +# define a20 (p->u.s[10]) +# define a21 (p->u.s[11]) +# define a22 (p->u.s[12]) +# define a23 (p->u.s[13]) +# define a24 (p->u.s[14]) +# define a30 (p->u.s[15]) +# define a31 (p->u.s[16]) +# define a32 (p->u.s[17]) +# define a33 (p->u.s[18]) +# define a34 (p->u.s[19]) +# define a40 (p->u.s[20]) +# define a41 (p->u.s[21]) +# define a42 (p->u.s[22]) +# define a43 (p->u.s[23]) +# define a44 (p->u.s[24]) # define ROL64(a,x) ((a<>(64-x))) for(i=0; i<24; i+=4){ - C0 = A00^A10^A20^A30^A40; - C1 = A01^A11^A21^A31^A41; - C2 = A02^A12^A22^A32^A42; - C3 = A03^A13^A23^A33^A43; - C4 = A04^A14^A24^A34^A44; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); + c0 = a00^a10^a20^a30^a40; + c1 = a01^a11^a21^a31^a41; + c2 = a02^a12^a22^a32^a42; + c3 = a03^a13^a23^a33^a43; + c4 = a04^a14^a24^a34^a44; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); - B0 = (A00^D0); - B1 = ROL64((A11^D1), 44); - B2 = ROL64((A22^D2), 43); - B3 = ROL64((A33^D3), 21); - B4 = ROL64((A44^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i]; - A11 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); + b0 = (a00^d0); + b1 = ROL64((a11^d1), 44); + b2 = ROL64((a22^d2), 43); + b3 = ROL64((a33^d3), 21); + b4 = ROL64((a44^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i]; + a11 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); - B2 = ROL64((A20^D0), 3); - B3 = ROL64((A31^D1), 45); - B4 = ROL64((A42^D2), 61); - B0 = ROL64((A03^D3), 28); - B1 = ROL64((A14^D4), 20); - A20 = B0 ^((~B1)& B2 ); - A31 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); + b2 = ROL64((a20^d0), 3); + b3 = ROL64((a31^d1), 45); + b4 = ROL64((a42^d2), 61); + b0 = ROL64((a03^d3), 28); + b1 = ROL64((a14^d4), 20); + a20 = b0 ^((~b1)& b2 ); + a31 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); - B4 = ROL64((A40^D0), 18); - B0 = ROL64((A01^D1), 1); - B1 = ROL64((A12^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A34^D4), 8); - A40 = B0 ^((~B1)& B2 ); - A01 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); + b4 = ROL64((a40^d0), 18); + b0 = ROL64((a01^d1), 1); + b1 = ROL64((a12^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a34^d4), 8); + a40 = b0 ^((~b1)& b2 ); + a01 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); - B1 = ROL64((A10^D0), 36); - B2 = ROL64((A21^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A43^D3), 56); - B0 = ROL64((A04^D4), 27); - A10 = B0 ^((~B1)& B2 ); - A21 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); + b1 = ROL64((a10^d0), 36); + b2 = ROL64((a21^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a43^d3), 56); + b0 = ROL64((a04^d4), 27); + a10 = b0 ^((~b1)& b2 ); + a21 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); - B3 = ROL64((A30^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A02^D2), 62); - B1 = ROL64((A13^D3), 55); - B2 = ROL64((A24^D4), 39); - A30 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); + b3 = ROL64((a30^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a02^d2), 62); + b1 = ROL64((a13^d3), 55); + b2 = ROL64((a24^d4), 39); + a30 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); - C0 = A00^A20^A40^A10^A30; - C1 = A11^A31^A01^A21^A41; - C2 = A22^A42^A12^A32^A02; - C3 = A33^A03^A23^A43^A13; - C4 = A44^A14^A34^A04^A24; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); + c0 = a00^a20^a40^a10^a30; + c1 = a11^a31^a01^a21^a41; + c2 = a22^a42^a12^a32^a02; + c3 = a33^a03^a23^a43^a13; + c4 = a44^a14^a34^a04^a24; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); - B0 = (A00^D0); - B1 = ROL64((A31^D1), 44); - B2 = ROL64((A12^D2), 43); - B3 = ROL64((A43^D3), 21); - B4 = ROL64((A24^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i+1]; - A31 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); + b0 = (a00^d0); + b1 = ROL64((a31^d1), 44); + b2 = ROL64((a12^d2), 43); + b3 = ROL64((a43^d3), 21); + b4 = ROL64((a24^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i+1]; + a31 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); - B2 = ROL64((A40^D0), 3); - B3 = ROL64((A21^D1), 45); - B4 = ROL64((A02^D2), 61); - B0 = ROL64((A33^D3), 28); - B1 = ROL64((A14^D4), 20); - A40 = B0 ^((~B1)& B2 ); - A21 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); + b2 = ROL64((a40^d0), 3); + b3 = ROL64((a21^d1), 45); + b4 = ROL64((a02^d2), 61); + b0 = ROL64((a33^d3), 28); + b1 = ROL64((a14^d4), 20); + a40 = b0 ^((~b1)& b2 ); + a21 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); - B4 = ROL64((A30^D0), 18); - B0 = ROL64((A11^D1), 1); - B1 = ROL64((A42^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A04^D4), 8); - A30 = B0 ^((~B1)& B2 ); - A11 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); + b4 = ROL64((a30^d0), 18); + b0 = ROL64((a11^d1), 1); + b1 = ROL64((a42^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a04^d4), 8); + a30 = b0 ^((~b1)& b2 ); + a11 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); - B1 = ROL64((A20^D0), 36); - B2 = ROL64((A01^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A13^D3), 56); - B0 = ROL64((A44^D4), 27); - A20 = B0 ^((~B1)& B2 ); - A01 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); + b1 = ROL64((a20^d0), 36); + b2 = ROL64((a01^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a13^d3), 56); + b0 = ROL64((a44^d4), 27); + a20 = b0 ^((~b1)& b2 ); + a01 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); - B3 = ROL64((A10^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A22^D2), 62); - B1 = ROL64((A03^D3), 55); - B2 = ROL64((A34^D4), 39); - A10 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); + b3 = ROL64((a10^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a22^d2), 62); + b1 = ROL64((a03^d3), 55); + b2 = ROL64((a34^d4), 39); + a10 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); - C0 = A00^A40^A30^A20^A10; - C1 = A31^A21^A11^A01^A41; - C2 = A12^A02^A42^A32^A22; - C3 = A43^A33^A23^A13^A03; - C4 = A24^A14^A04^A44^A34; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); + c0 = a00^a40^a30^a20^a10; + c1 = a31^a21^a11^a01^a41; + c2 = a12^a02^a42^a32^a22; + c3 = a43^a33^a23^a13^a03; + c4 = a24^a14^a04^a44^a34; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); - B0 = (A00^D0); - B1 = ROL64((A21^D1), 44); - B2 = ROL64((A42^D2), 43); - B3 = ROL64((A13^D3), 21); - B4 = ROL64((A34^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i+2]; - A21 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); + b0 = (a00^d0); + b1 = ROL64((a21^d1), 44); + b2 = ROL64((a42^d2), 43); + b3 = ROL64((a13^d3), 21); + b4 = ROL64((a34^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i+2]; + a21 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); - B2 = ROL64((A30^D0), 3); - B3 = ROL64((A01^D1), 45); - B4 = ROL64((A22^D2), 61); - B0 = ROL64((A43^D3), 28); - B1 = ROL64((A14^D4), 20); - A30 = B0 ^((~B1)& B2 ); - A01 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); + b2 = ROL64((a30^d0), 3); + b3 = ROL64((a01^d1), 45); + b4 = ROL64((a22^d2), 61); + b0 = ROL64((a43^d3), 28); + b1 = ROL64((a14^d4), 20); + a30 = b0 ^((~b1)& b2 ); + a01 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); - B4 = ROL64((A10^D0), 18); - B0 = ROL64((A31^D1), 1); - B1 = ROL64((A02^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A44^D4), 8); - A10 = B0 ^((~B1)& B2 ); - A31 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); + b4 = ROL64((a10^d0), 18); + b0 = ROL64((a31^d1), 1); + b1 = ROL64((a02^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a44^d4), 8); + a10 = b0 ^((~b1)& b2 ); + a31 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); - B1 = ROL64((A40^D0), 36); - B2 = ROL64((A11^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A03^D3), 56); - B0 = ROL64((A24^D4), 27); - A40 = B0 ^((~B1)& B2 ); - A11 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); + b1 = ROL64((a40^d0), 36); + b2 = ROL64((a11^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a03^d3), 56); + b0 = ROL64((a24^d4), 27); + a40 = b0 ^((~b1)& b2 ); + a11 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); - B3 = ROL64((A20^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A12^D2), 62); - B1 = ROL64((A33^D3), 55); - B2 = ROL64((A04^D4), 39); - A20 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); + b3 = ROL64((a20^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a12^d2), 62); + b1 = ROL64((a33^d3), 55); + b2 = ROL64((a04^d4), 39); + a20 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); - C0 = A00^A30^A10^A40^A20; - C1 = A21^A01^A31^A11^A41; - C2 = A42^A22^A02^A32^A12; - C3 = A13^A43^A23^A03^A33; - C4 = A34^A14^A44^A24^A04; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); + c0 = a00^a30^a10^a40^a20; + c1 = a21^a01^a31^a11^a41; + c2 = a42^a22^a02^a32^a12; + c3 = a13^a43^a23^a03^a33; + c4 = a34^a14^a44^a24^a04; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); - B0 = (A00^D0); - B1 = ROL64((A01^D1), 44); - B2 = ROL64((A02^D2), 43); - B3 = ROL64((A03^D3), 21); - B4 = ROL64((A04^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i+3]; - A01 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); + b0 = (a00^d0); + b1 = ROL64((a01^d1), 44); + b2 = ROL64((a02^d2), 43); + b3 = ROL64((a03^d3), 21); + b4 = ROL64((a04^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i+3]; + a01 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); - B2 = ROL64((A10^D0), 3); - B3 = ROL64((A11^D1), 45); - B4 = ROL64((A12^D2), 61); - B0 = ROL64((A13^D3), 28); - B1 = ROL64((A14^D4), 20); - A10 = B0 ^((~B1)& B2 ); - A11 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); + b2 = ROL64((a10^d0), 3); + b3 = ROL64((a11^d1), 45); + b4 = ROL64((a12^d2), 61); + b0 = ROL64((a13^d3), 28); + b1 = ROL64((a14^d4), 20); + a10 = b0 ^((~b1)& b2 ); + a11 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); - B4 = ROL64((A20^D0), 18); - B0 = ROL64((A21^D1), 1); - B1 = ROL64((A22^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A24^D4), 8); - A20 = B0 ^((~B1)& B2 ); - A21 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); + b4 = ROL64((a20^d0), 18); + b0 = ROL64((a21^d1), 1); + b1 = ROL64((a22^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a24^d4), 8); + a20 = b0 ^((~b1)& b2 ); + a21 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); - B1 = ROL64((A30^D0), 36); - B2 = ROL64((A31^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A33^D3), 56); - B0 = ROL64((A34^D4), 27); - A30 = B0 ^((~B1)& B2 ); - A31 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); + b1 = ROL64((a30^d0), 36); + b2 = ROL64((a31^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a33^d3), 56); + b0 = ROL64((a34^d4), 27); + a30 = b0 ^((~b1)& b2 ); + a31 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); - B3 = ROL64((A40^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A42^D2), 62); - B1 = ROL64((A43^D3), 55); - B2 = ROL64((A44^D4), 39); - A40 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); + b3 = ROL64((a40^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a42^d2), 62); + b1 = ROL64((a43^d3), 55); + b2 = ROL64((a44^d4), 39); + a40 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); } } diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index 1ac1712f4e..81bef139a3 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -18,6 +18,12 @@ SQLITE_EXTENSION_INIT1 #ifndef SQLITE_AMALGAMATION +# if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +# endif +# if defined(NDEBUG) && defined(SQLITE_DEBUG) +# undef NDEBUG +# endif # include # include # include @@ -652,6 +658,79 @@ static void editDist3ConfigDelete(void *pIn){ sqlite3_free(p); } +/* Compare the FROM values of two EditDist3Cost objects, for sorting. +** Return negative, zero, or positive if the A is less than, equal to, +** or greater than B. +*/ +static int editDist3CostCompare(EditDist3Cost *pA, EditDist3Cost *pB){ + int n = pA->nFrom; + int rc; + if( n>pB->nFrom ) n = pB->nFrom; + rc = strncmp(pA->a, pB->a, n); + if( rc==0 ) rc = pA->nFrom - pB->nFrom; + return rc; +} + +/* +** Merge together two sorted lists of EditDist3Cost objects, in order +** of increasing FROM. +*/ +static EditDist3Cost *editDist3CostMerge( + EditDist3Cost *pA, + EditDist3Cost *pB +){ + EditDist3Cost *pHead = 0; + EditDist3Cost **ppTail = &pHead; + EditDist3Cost *p; + while( pA && pB ){ + if( editDist3CostCompare(pA,pB)<=0 ){ + p = pA; + pA = pA->pNext; + }else{ + p = pB; + pB = pB->pNext; + } + *ppTail = p; + ppTail = &p->pNext; + } + if( pA ){ + *ppTail = pA; + }else{ + *ppTail = pB; + } + return pHead; +} + +/* +** Sort a list of EditDist3Cost objects into order of increasing FROM +*/ +static EditDist3Cost *editDist3CostSort(EditDist3Cost *pList){ + EditDist3Cost *ap[60], *p; + int i; + int mx = 0; + ap[0] = 0; + ap[1] = 0; + while( pList ){ + p = pList; + pList = p->pNext; + p->pNext = 0; + for(i=0; ap[i]; i++){ + p = editDist3CostMerge(ap[i],p); + ap[i] = 0; + } + ap[i] = p; + if( i>mx ){ + mx = i; + ap[i+1] = 0; + } + } + p = 0; + for(i=0; i<=mx; i++){ + if( ap[i] ) p = editDist3CostMerge(p,ap[i]); + } + return p; +} + /* ** Load all edit-distance weights from a table. */ @@ -685,6 +764,7 @@ static int editDist3ConfigLoad( assert( zTo!=0 || nTo==0 ); if( nFrom>100 || nTo>100 ) continue; if( iCost<0 ) continue; + if( iCost>=10000 ) continue; /* Costs above 10K are considered infinite */ if( pLang==0 || iLang!=iLangPrev ){ EditDist3Lang *pNew; pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0])); @@ -722,6 +802,12 @@ static int editDist3ConfigLoad( } rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK ){ + int iLang; + for(iLang=0; iLangnLang; iLang++){ + p->a[iLang].pCost = editDist3CostSort(p->a[iLang].pCost); + } + } return rc; } @@ -749,6 +835,8 @@ static int utf8Len(unsigned char c, int N){ ** the given string. */ static int matchTo(EditDist3Cost *p, const char *z, int n){ + assert( n>0 ); + if( p->a[p->nFrom]!=z[0] ) return 0; if( p->nTo>n ) return 0; if( strncmp(p->a+p->nFrom, z, p->nTo)!=0 ) return 0; return 1; @@ -760,7 +848,10 @@ static int matchTo(EditDist3Cost *p, const char *z, int n){ */ static int matchFrom(EditDist3Cost *p, const char *z, int n){ assert( p->nFrom<=n ); - if( strncmp(p->a, z, p->nFrom)!=0 ) return 0; + if( p->nFrom ){ + if( p->a[0]!=z[0] ) return 0; + if( strncmp(p->a, z, p->nFrom)!=0 ) return 0; + } return 1; } @@ -776,7 +867,9 @@ static int matchFromTo( ){ int b1 = pStr->a[n1].nByte; if( b1>n2 ) return 0; - if( memcmp(pStr->z+n1, z2, b1)!=0 ) return 0; + assert( b1>0 ); + if( pStr->z[n1]!=z2[0] ) return 0; + if( strncmp(pStr->z+n1, z2, b1)!=0 ) return 0; return 1; } @@ -858,9 +951,6 @@ static EditDist3FromString *editDist3FromStringNew( /* ** Update entry m[i] such that it is the minimum of its current value ** and m[j]+iCost. -** -** If the iCost is 1,000,000 or greater, then consider the cost to be -** infinite and skip the update. */ static void updateCost( unsigned int *m, @@ -868,11 +958,11 @@ static void updateCost( int j, int iCost ){ + unsigned int b; assert( iCost>=0 ); - if( iCost<10000 ){ - unsigned int b = m[j] + iCost; - if( bpCost; p; p=p->pNext){ EditDist3Cost **apNew; - if( p->nFrom>0 ) continue; + if( p->nFrom>0 ) break; if( i2+p->nTo>n2 ) continue; + if( p->a[0]>z2[i2] ) break; if( matchTo(p, z2+i2, n2-i2)==0 ) continue; a2[i2].nIns++; apNew = sqlite3_realloc64(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns); @@ -1122,15 +1213,17 @@ static int editDist3Install(sqlite3 *db){ if( pConfig==0 ) return SQLITE_NOMEM; memset(pConfig, 0, sizeof(*pConfig)); rc = sqlite3_create_function_v2(db, "editdist3", - 2, SQLITE_UTF8, pConfig, editDist3SqlFunc, 0, 0, 0); + 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, pConfig, + editDist3SqlFunc, 0, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_function_v2(db, "editdist3", - 3, SQLITE_UTF8, pConfig, editDist3SqlFunc, 0, 0, 0); + 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, pConfig, + editDist3SqlFunc, 0, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_create_function_v2(db, "editdist3", - 1, SQLITE_UTF8, pConfig, editDist3SqlFunc, 0, 0, - editDist3ConfigDelete); + 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, pConfig, + editDist3SqlFunc, 0, 0, editDist3ConfigDelete); }else{ sqlite3_free(pConfig); } @@ -1198,404 +1291,415 @@ static int utf8Charlen(const char *zIn, int nIn){ return nChar; } +typedef struct Transliteration Transliteration; +struct Transliteration { + unsigned short int cFrom; + unsigned char cTo0, cTo1, cTo2, cTo3; +#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS + unsigned char cTo4; +#endif +}; + /* ** Table of translations from unicode characters into ASCII. */ -static const struct { - unsigned short int cFrom; - unsigned char cTo0, cTo1; -} translit[] = { - { 0x00A0, 0x20, 0x00 }, /*   to */ - { 0x00B5, 0x75, 0x00 }, /* µ to u */ - { 0x00C0, 0x41, 0x00 }, /* À to A */ - { 0x00C1, 0x41, 0x00 }, /* Á to A */ - { 0x00C2, 0x41, 0x00 }, /*  to A */ - { 0x00C3, 0x41, 0x00 }, /* à to A */ - { 0x00C4, 0x41, 0x65 }, /* Ä to Ae */ - { 0x00C5, 0x41, 0x61 }, /* Å to Aa */ - { 0x00C6, 0x41, 0x45 }, /* Æ to AE */ - { 0x00C7, 0x43, 0x00 }, /* Ç to C */ - { 0x00C8, 0x45, 0x00 }, /* È to E */ - { 0x00C9, 0x45, 0x00 }, /* É to E */ - { 0x00CA, 0x45, 0x00 }, /* Ê to E */ - { 0x00CB, 0x45, 0x00 }, /* Ë to E */ - { 0x00CC, 0x49, 0x00 }, /* Ì to I */ - { 0x00CD, 0x49, 0x00 }, /* Í to I */ - { 0x00CE, 0x49, 0x00 }, /* Î to I */ - { 0x00CF, 0x49, 0x00 }, /* Ï to I */ - { 0x00D0, 0x44, 0x00 }, /* Ð to D */ - { 0x00D1, 0x4E, 0x00 }, /* Ñ to N */ - { 0x00D2, 0x4F, 0x00 }, /* Ò to O */ - { 0x00D3, 0x4F, 0x00 }, /* Ó to O */ - { 0x00D4, 0x4F, 0x00 }, /* Ô to O */ - { 0x00D5, 0x4F, 0x00 }, /* Õ to O */ - { 0x00D6, 0x4F, 0x65 }, /* Ö to Oe */ - { 0x00D7, 0x78, 0x00 }, /* × to x */ - { 0x00D8, 0x4F, 0x00 }, /* Ø to O */ - { 0x00D9, 0x55, 0x00 }, /* Ù to U */ - { 0x00DA, 0x55, 0x00 }, /* Ú to U */ - { 0x00DB, 0x55, 0x00 }, /* Û to U */ - { 0x00DC, 0x55, 0x65 }, /* Ü to Ue */ - { 0x00DD, 0x59, 0x00 }, /* Ý to Y */ - { 0x00DE, 0x54, 0x68 }, /* Þ to Th */ - { 0x00DF, 0x73, 0x73 }, /* ß to ss */ - { 0x00E0, 0x61, 0x00 }, /* à to a */ - { 0x00E1, 0x61, 0x00 }, /* á to a */ - { 0x00E2, 0x61, 0x00 }, /* â to a */ - { 0x00E3, 0x61, 0x00 }, /* ã to a */ - { 0x00E4, 0x61, 0x65 }, /* ä to ae */ - { 0x00E5, 0x61, 0x61 }, /* å to aa */ - { 0x00E6, 0x61, 0x65 }, /* æ to ae */ - { 0x00E7, 0x63, 0x00 }, /* ç to c */ - { 0x00E8, 0x65, 0x00 }, /* è to e */ - { 0x00E9, 0x65, 0x00 }, /* é to e */ - { 0x00EA, 0x65, 0x00 }, /* ê to e */ - { 0x00EB, 0x65, 0x00 }, /* ë to e */ - { 0x00EC, 0x69, 0x00 }, /* ì to i */ - { 0x00ED, 0x69, 0x00 }, /* í to i */ - { 0x00EE, 0x69, 0x00 }, /* î to i */ - { 0x00EF, 0x69, 0x00 }, /* ï to i */ - { 0x00F0, 0x64, 0x00 }, /* ð to d */ - { 0x00F1, 0x6E, 0x00 }, /* ñ to n */ - { 0x00F2, 0x6F, 0x00 }, /* ò to o */ - { 0x00F3, 0x6F, 0x00 }, /* ó to o */ - { 0x00F4, 0x6F, 0x00 }, /* ô to o */ - { 0x00F5, 0x6F, 0x00 }, /* õ to o */ - { 0x00F6, 0x6F, 0x65 }, /* ö to oe */ - { 0x00F7, 0x3A, 0x00 }, /* ÷ to : */ - { 0x00F8, 0x6F, 0x00 }, /* ø to o */ - { 0x00F9, 0x75, 0x00 }, /* ù to u */ - { 0x00FA, 0x75, 0x00 }, /* ú to u */ - { 0x00FB, 0x75, 0x00 }, /* û to u */ - { 0x00FC, 0x75, 0x65 }, /* ü to ue */ - { 0x00FD, 0x79, 0x00 }, /* ý to y */ - { 0x00FE, 0x74, 0x68 }, /* þ to th */ - { 0x00FF, 0x79, 0x00 }, /* ÿ to y */ - { 0x0100, 0x41, 0x00 }, /* Ā to A */ - { 0x0101, 0x61, 0x00 }, /* ā to a */ - { 0x0102, 0x41, 0x00 }, /* Ă to A */ - { 0x0103, 0x61, 0x00 }, /* ă to a */ - { 0x0104, 0x41, 0x00 }, /* Ą to A */ - { 0x0105, 0x61, 0x00 }, /* ą to a */ - { 0x0106, 0x43, 0x00 }, /* Ć to C */ - { 0x0107, 0x63, 0x00 }, /* ć to c */ - { 0x0108, 0x43, 0x68 }, /* Ĉ to Ch */ - { 0x0109, 0x63, 0x68 }, /* ĉ to ch */ - { 0x010A, 0x43, 0x00 }, /* Ċ to C */ - { 0x010B, 0x63, 0x00 }, /* ċ to c */ - { 0x010C, 0x43, 0x00 }, /* Č to C */ - { 0x010D, 0x63, 0x00 }, /* č to c */ - { 0x010E, 0x44, 0x00 }, /* Ď to D */ - { 0x010F, 0x64, 0x00 }, /* ď to d */ - { 0x0110, 0x44, 0x00 }, /* Đ to D */ - { 0x0111, 0x64, 0x00 }, /* đ to d */ - { 0x0112, 0x45, 0x00 }, /* Ē to E */ - { 0x0113, 0x65, 0x00 }, /* ē to e */ - { 0x0114, 0x45, 0x00 }, /* Ĕ to E */ - { 0x0115, 0x65, 0x00 }, /* ĕ to e */ - { 0x0116, 0x45, 0x00 }, /* Ė to E */ - { 0x0117, 0x65, 0x00 }, /* ė to e */ - { 0x0118, 0x45, 0x00 }, /* Ę to E */ - { 0x0119, 0x65, 0x00 }, /* ę to e */ - { 0x011A, 0x45, 0x00 }, /* Ě to E */ - { 0x011B, 0x65, 0x00 }, /* ě to e */ - { 0x011C, 0x47, 0x68 }, /* Ĝ to Gh */ - { 0x011D, 0x67, 0x68 }, /* ĝ to gh */ - { 0x011E, 0x47, 0x00 }, /* Ğ to G */ - { 0x011F, 0x67, 0x00 }, /* ğ to g */ - { 0x0120, 0x47, 0x00 }, /* Ġ to G */ - { 0x0121, 0x67, 0x00 }, /* ġ to g */ - { 0x0122, 0x47, 0x00 }, /* Ģ to G */ - { 0x0123, 0x67, 0x00 }, /* ģ to g */ - { 0x0124, 0x48, 0x68 }, /* Ĥ to Hh */ - { 0x0125, 0x68, 0x68 }, /* ĥ to hh */ - { 0x0126, 0x48, 0x00 }, /* Ħ to H */ - { 0x0127, 0x68, 0x00 }, /* ħ to h */ - { 0x0128, 0x49, 0x00 }, /* Ĩ to I */ - { 0x0129, 0x69, 0x00 }, /* ĩ to i */ - { 0x012A, 0x49, 0x00 }, /* Ī to I */ - { 0x012B, 0x69, 0x00 }, /* ī to i */ - { 0x012C, 0x49, 0x00 }, /* Ĭ to I */ - { 0x012D, 0x69, 0x00 }, /* ĭ to i */ - { 0x012E, 0x49, 0x00 }, /* Į to I */ - { 0x012F, 0x69, 0x00 }, /* į to i */ - { 0x0130, 0x49, 0x00 }, /* İ to I */ - { 0x0131, 0x69, 0x00 }, /* ı to i */ - { 0x0132, 0x49, 0x4A }, /* IJ to IJ */ - { 0x0133, 0x69, 0x6A }, /* ij to ij */ - { 0x0134, 0x4A, 0x68 }, /* Ĵ to Jh */ - { 0x0135, 0x6A, 0x68 }, /* ĵ to jh */ - { 0x0136, 0x4B, 0x00 }, /* Ķ to K */ - { 0x0137, 0x6B, 0x00 }, /* ķ to k */ - { 0x0138, 0x6B, 0x00 }, /* ĸ to k */ - { 0x0139, 0x4C, 0x00 }, /* Ĺ to L */ - { 0x013A, 0x6C, 0x00 }, /* ĺ to l */ - { 0x013B, 0x4C, 0x00 }, /* Ļ to L */ - { 0x013C, 0x6C, 0x00 }, /* ļ to l */ - { 0x013D, 0x4C, 0x00 }, /* Ľ to L */ - { 0x013E, 0x6C, 0x00 }, /* ľ to l */ - { 0x013F, 0x4C, 0x2E }, /* Ŀ to L. */ - { 0x0140, 0x6C, 0x2E }, /* ŀ to l. */ - { 0x0141, 0x4C, 0x00 }, /* Ł to L */ - { 0x0142, 0x6C, 0x00 }, /* ł to l */ - { 0x0143, 0x4E, 0x00 }, /* Ń to N */ - { 0x0144, 0x6E, 0x00 }, /* ń to n */ - { 0x0145, 0x4E, 0x00 }, /* Ņ to N */ - { 0x0146, 0x6E, 0x00 }, /* ņ to n */ - { 0x0147, 0x4E, 0x00 }, /* Ň to N */ - { 0x0148, 0x6E, 0x00 }, /* ň to n */ - { 0x0149, 0x27, 0x6E }, /* ʼn to 'n */ - { 0x014A, 0x4E, 0x47 }, /* Ŋ to NG */ - { 0x014B, 0x6E, 0x67 }, /* ŋ to ng */ - { 0x014C, 0x4F, 0x00 }, /* Ō to O */ - { 0x014D, 0x6F, 0x00 }, /* ō to o */ - { 0x014E, 0x4F, 0x00 }, /* Ŏ to O */ - { 0x014F, 0x6F, 0x00 }, /* ŏ to o */ - { 0x0150, 0x4F, 0x00 }, /* Ő to O */ - { 0x0151, 0x6F, 0x00 }, /* ő to o */ - { 0x0152, 0x4F, 0x45 }, /* Œ to OE */ - { 0x0153, 0x6F, 0x65 }, /* œ to oe */ - { 0x0154, 0x52, 0x00 }, /* Ŕ to R */ - { 0x0155, 0x72, 0x00 }, /* ŕ to r */ - { 0x0156, 0x52, 0x00 }, /* Ŗ to R */ - { 0x0157, 0x72, 0x00 }, /* ŗ to r */ - { 0x0158, 0x52, 0x00 }, /* Ř to R */ - { 0x0159, 0x72, 0x00 }, /* ř to r */ - { 0x015A, 0x53, 0x00 }, /* Ś to S */ - { 0x015B, 0x73, 0x00 }, /* ś to s */ - { 0x015C, 0x53, 0x68 }, /* Ŝ to Sh */ - { 0x015D, 0x73, 0x68 }, /* ŝ to sh */ - { 0x015E, 0x53, 0x00 }, /* Ş to S */ - { 0x015F, 0x73, 0x00 }, /* ş to s */ - { 0x0160, 0x53, 0x00 }, /* Š to S */ - { 0x0161, 0x73, 0x00 }, /* š to s */ - { 0x0162, 0x54, 0x00 }, /* Ţ to T */ - { 0x0163, 0x74, 0x00 }, /* ţ to t */ - { 0x0164, 0x54, 0x00 }, /* Ť to T */ - { 0x0165, 0x74, 0x00 }, /* ť to t */ - { 0x0166, 0x54, 0x00 }, /* Ŧ to T */ - { 0x0167, 0x74, 0x00 }, /* ŧ to t */ - { 0x0168, 0x55, 0x00 }, /* Ũ to U */ - { 0x0169, 0x75, 0x00 }, /* ũ to u */ - { 0x016A, 0x55, 0x00 }, /* Ū to U */ - { 0x016B, 0x75, 0x00 }, /* ū to u */ - { 0x016C, 0x55, 0x00 }, /* Ŭ to U */ - { 0x016D, 0x75, 0x00 }, /* ŭ to u */ - { 0x016E, 0x55, 0x00 }, /* Ů to U */ - { 0x016F, 0x75, 0x00 }, /* ů to u */ - { 0x0170, 0x55, 0x00 }, /* Ű to U */ - { 0x0171, 0x75, 0x00 }, /* ű to u */ - { 0x0172, 0x55, 0x00 }, /* Ų to U */ - { 0x0173, 0x75, 0x00 }, /* ų to u */ - { 0x0174, 0x57, 0x00 }, /* Ŵ to W */ - { 0x0175, 0x77, 0x00 }, /* ŵ to w */ - { 0x0176, 0x59, 0x00 }, /* Ŷ to Y */ - { 0x0177, 0x79, 0x00 }, /* ŷ to y */ - { 0x0178, 0x59, 0x00 }, /* Ÿ to Y */ - { 0x0179, 0x5A, 0x00 }, /* Ź to Z */ - { 0x017A, 0x7A, 0x00 }, /* ź to z */ - { 0x017B, 0x5A, 0x00 }, /* Ż to Z */ - { 0x017C, 0x7A, 0x00 }, /* ż to z */ - { 0x017D, 0x5A, 0x00 }, /* Ž to Z */ - { 0x017E, 0x7A, 0x00 }, /* ž to z */ - { 0x017F, 0x73, 0x00 }, /* ſ to s */ - { 0x0192, 0x66, 0x00 }, /* ƒ to f */ - { 0x0218, 0x53, 0x00 }, /* Ș to S */ - { 0x0219, 0x73, 0x00 }, /* ș to s */ - { 0x021A, 0x54, 0x00 }, /* Ț to T */ - { 0x021B, 0x74, 0x00 }, /* ț to t */ - { 0x0386, 0x41, 0x00 }, /* Ά to A */ - { 0x0388, 0x45, 0x00 }, /* Έ to E */ - { 0x0389, 0x49, 0x00 }, /* Ή to I */ - { 0x038A, 0x49, 0x00 }, /* Ί to I */ - { 0x038C, 0x4f, 0x00 }, /* Ό to O */ - { 0x038E, 0x59, 0x00 }, /* Ύ to Y */ - { 0x038F, 0x4f, 0x00 }, /* Ώ to O */ - { 0x0390, 0x69, 0x00 }, /* ΐ to i */ - { 0x0391, 0x41, 0x00 }, /* Α to A */ - { 0x0392, 0x42, 0x00 }, /* Β to B */ - { 0x0393, 0x47, 0x00 }, /* Γ to G */ - { 0x0394, 0x44, 0x00 }, /* Δ to D */ - { 0x0395, 0x45, 0x00 }, /* Ε to E */ - { 0x0396, 0x5a, 0x00 }, /* Ζ to Z */ - { 0x0397, 0x49, 0x00 }, /* Η to I */ - { 0x0398, 0x54, 0x68 }, /* Θ to Th */ - { 0x0399, 0x49, 0x00 }, /* Ι to I */ - { 0x039A, 0x4b, 0x00 }, /* Κ to K */ - { 0x039B, 0x4c, 0x00 }, /* Λ to L */ - { 0x039C, 0x4d, 0x00 }, /* Μ to M */ - { 0x039D, 0x4e, 0x00 }, /* Ν to N */ - { 0x039E, 0x58, 0x00 }, /* Ξ to X */ - { 0x039F, 0x4f, 0x00 }, /* Ο to O */ - { 0x03A0, 0x50, 0x00 }, /* Π to P */ - { 0x03A1, 0x52, 0x00 }, /* Ρ to R */ - { 0x03A3, 0x53, 0x00 }, /* Σ to S */ - { 0x03A4, 0x54, 0x00 }, /* Τ to T */ - { 0x03A5, 0x59, 0x00 }, /* Υ to Y */ - { 0x03A6, 0x46, 0x00 }, /* Φ to F */ - { 0x03A7, 0x43, 0x68 }, /* Χ to Ch */ - { 0x03A8, 0x50, 0x73 }, /* Ψ to Ps */ - { 0x03A9, 0x4f, 0x00 }, /* Ω to O */ - { 0x03AA, 0x49, 0x00 }, /* Ϊ to I */ - { 0x03AB, 0x59, 0x00 }, /* Ϋ to Y */ - { 0x03AC, 0x61, 0x00 }, /* ά to a */ - { 0x03AD, 0x65, 0x00 }, /* έ to e */ - { 0x03AE, 0x69, 0x00 }, /* ή to i */ - { 0x03AF, 0x69, 0x00 }, /* ί to i */ - { 0x03B1, 0x61, 0x00 }, /* α to a */ - { 0x03B2, 0x62, 0x00 }, /* β to b */ - { 0x03B3, 0x67, 0x00 }, /* γ to g */ - { 0x03B4, 0x64, 0x00 }, /* δ to d */ - { 0x03B5, 0x65, 0x00 }, /* ε to e */ - { 0x03B6, 0x7a, 0x00 }, /* ζ to z */ - { 0x03B7, 0x69, 0x00 }, /* η to i */ - { 0x03B8, 0x74, 0x68 }, /* θ to th */ - { 0x03B9, 0x69, 0x00 }, /* ι to i */ - { 0x03BA, 0x6b, 0x00 }, /* κ to k */ - { 0x03BB, 0x6c, 0x00 }, /* λ to l */ - { 0x03BC, 0x6d, 0x00 }, /* μ to m */ - { 0x03BD, 0x6e, 0x00 }, /* ν to n */ - { 0x03BE, 0x78, 0x00 }, /* ξ to x */ - { 0x03BF, 0x6f, 0x00 }, /* ο to o */ - { 0x03C0, 0x70, 0x00 }, /* π to p */ - { 0x03C1, 0x72, 0x00 }, /* ρ to r */ - { 0x03C3, 0x73, 0x00 }, /* σ to s */ - { 0x03C4, 0x74, 0x00 }, /* τ to t */ - { 0x03C5, 0x79, 0x00 }, /* υ to y */ - { 0x03C6, 0x66, 0x00 }, /* φ to f */ - { 0x03C7, 0x63, 0x68 }, /* χ to ch */ - { 0x03C8, 0x70, 0x73 }, /* ψ to ps */ - { 0x03C9, 0x6f, 0x00 }, /* ω to o */ - { 0x03CA, 0x69, 0x00 }, /* ϊ to i */ - { 0x03CB, 0x79, 0x00 }, /* ϋ to y */ - { 0x03CC, 0x6f, 0x00 }, /* ό to o */ - { 0x03CD, 0x79, 0x00 }, /* ύ to y */ - { 0x03CE, 0x69, 0x00 }, /* ώ to i */ - { 0x0400, 0x45, 0x00 }, /* Ѐ to E */ - { 0x0401, 0x45, 0x00 }, /* Ё to E */ - { 0x0402, 0x44, 0x00 }, /* Ђ to D */ - { 0x0403, 0x47, 0x00 }, /* Ѓ to G */ - { 0x0404, 0x45, 0x00 }, /* Є to E */ - { 0x0405, 0x5a, 0x00 }, /* Ѕ to Z */ - { 0x0406, 0x49, 0x00 }, /* І to I */ - { 0x0407, 0x49, 0x00 }, /* Ї to I */ - { 0x0408, 0x4a, 0x00 }, /* Ј to J */ - { 0x0409, 0x49, 0x00 }, /* Љ to I */ - { 0x040A, 0x4e, 0x00 }, /* Њ to N */ - { 0x040B, 0x44, 0x00 }, /* Ћ to D */ - { 0x040C, 0x4b, 0x00 }, /* Ќ to K */ - { 0x040D, 0x49, 0x00 }, /* Ѝ to I */ - { 0x040E, 0x55, 0x00 }, /* Ў to U */ - { 0x040F, 0x44, 0x00 }, /* Џ to D */ - { 0x0410, 0x41, 0x00 }, /* А to A */ - { 0x0411, 0x42, 0x00 }, /* Б to B */ - { 0x0412, 0x56, 0x00 }, /* В to V */ - { 0x0413, 0x47, 0x00 }, /* Г to G */ - { 0x0414, 0x44, 0x00 }, /* Д to D */ - { 0x0415, 0x45, 0x00 }, /* Е to E */ - { 0x0416, 0x5a, 0x68 }, /* Ж to Zh */ - { 0x0417, 0x5a, 0x00 }, /* З to Z */ - { 0x0418, 0x49, 0x00 }, /* И to I */ - { 0x0419, 0x49, 0x00 }, /* Й to I */ - { 0x041A, 0x4b, 0x00 }, /* К to K */ - { 0x041B, 0x4c, 0x00 }, /* Л to L */ - { 0x041C, 0x4d, 0x00 }, /* М to M */ - { 0x041D, 0x4e, 0x00 }, /* Н to N */ - { 0x041E, 0x4f, 0x00 }, /* О to O */ - { 0x041F, 0x50, 0x00 }, /* П to P */ - { 0x0420, 0x52, 0x00 }, /* Р to R */ - { 0x0421, 0x53, 0x00 }, /* С to S */ - { 0x0422, 0x54, 0x00 }, /* Т to T */ - { 0x0423, 0x55, 0x00 }, /* У to U */ - { 0x0424, 0x46, 0x00 }, /* Ф to F */ - { 0x0425, 0x4b, 0x68 }, /* Х to Kh */ - { 0x0426, 0x54, 0x63 }, /* Ц to Tc */ - { 0x0427, 0x43, 0x68 }, /* Ч to Ch */ - { 0x0428, 0x53, 0x68 }, /* Ш to Sh */ - { 0x0429, 0x53, 0x68 }, /* Щ to Shch */ - { 0x042A, 0x61, 0x00 }, /* to A */ - { 0x042B, 0x59, 0x00 }, /* Ы to Y */ - { 0x042C, 0x59, 0x00 }, /* to Y */ - { 0x042D, 0x45, 0x00 }, /* Э to E */ - { 0x042E, 0x49, 0x75 }, /* Ю to Iu */ - { 0x042F, 0x49, 0x61 }, /* Я to Ia */ - { 0x0430, 0x61, 0x00 }, /* а to a */ - { 0x0431, 0x62, 0x00 }, /* б to b */ - { 0x0432, 0x76, 0x00 }, /* в to v */ - { 0x0433, 0x67, 0x00 }, /* г to g */ - { 0x0434, 0x64, 0x00 }, /* д to d */ - { 0x0435, 0x65, 0x00 }, /* е to e */ - { 0x0436, 0x7a, 0x68 }, /* ж to zh */ - { 0x0437, 0x7a, 0x00 }, /* з to z */ - { 0x0438, 0x69, 0x00 }, /* и to i */ - { 0x0439, 0x69, 0x00 }, /* й to i */ - { 0x043A, 0x6b, 0x00 }, /* к to k */ - { 0x043B, 0x6c, 0x00 }, /* л to l */ - { 0x043C, 0x6d, 0x00 }, /* м to m */ - { 0x043D, 0x6e, 0x00 }, /* н to n */ - { 0x043E, 0x6f, 0x00 }, /* о to o */ - { 0x043F, 0x70, 0x00 }, /* п to p */ - { 0x0440, 0x72, 0x00 }, /* р to r */ - { 0x0441, 0x73, 0x00 }, /* с to s */ - { 0x0442, 0x74, 0x00 }, /* т to t */ - { 0x0443, 0x75, 0x00 }, /* у to u */ - { 0x0444, 0x66, 0x00 }, /* ф to f */ - { 0x0445, 0x6b, 0x68 }, /* х to kh */ - { 0x0446, 0x74, 0x63 }, /* ц to tc */ - { 0x0447, 0x63, 0x68 }, /* ч to ch */ - { 0x0448, 0x73, 0x68 }, /* ш to sh */ - { 0x0449, 0x73, 0x68 }, /* щ to shch */ - { 0x044A, 0x61, 0x00 }, /* to a */ - { 0x044B, 0x79, 0x00 }, /* ы to y */ - { 0x044C, 0x79, 0x00 }, /* to y */ - { 0x044D, 0x65, 0x00 }, /* э to e */ - { 0x044E, 0x69, 0x75 }, /* ю to iu */ - { 0x044F, 0x69, 0x61 }, /* я to ia */ - { 0x0450, 0x65, 0x00 }, /* ѐ to e */ - { 0x0451, 0x65, 0x00 }, /* ё to e */ - { 0x0452, 0x64, 0x00 }, /* ђ to d */ - { 0x0453, 0x67, 0x00 }, /* ѓ to g */ - { 0x0454, 0x65, 0x00 }, /* є to e */ - { 0x0455, 0x7a, 0x00 }, /* ѕ to z */ - { 0x0456, 0x69, 0x00 }, /* і to i */ - { 0x0457, 0x69, 0x00 }, /* ї to i */ - { 0x0458, 0x6a, 0x00 }, /* ј to j */ - { 0x0459, 0x69, 0x00 }, /* љ to i */ - { 0x045A, 0x6e, 0x00 }, /* њ to n */ - { 0x045B, 0x64, 0x00 }, /* ћ to d */ - { 0x045C, 0x6b, 0x00 }, /* ќ to k */ - { 0x045D, 0x69, 0x00 }, /* ѝ to i */ - { 0x045E, 0x75, 0x00 }, /* ў to u */ - { 0x045F, 0x64, 0x00 }, /* џ to d */ - { 0x1E02, 0x42, 0x00 }, /* Ḃ to B */ - { 0x1E03, 0x62, 0x00 }, /* ḃ to b */ - { 0x1E0A, 0x44, 0x00 }, /* Ḋ to D */ - { 0x1E0B, 0x64, 0x00 }, /* ḋ to d */ - { 0x1E1E, 0x46, 0x00 }, /* Ḟ to F */ - { 0x1E1F, 0x66, 0x00 }, /* ḟ to f */ - { 0x1E40, 0x4D, 0x00 }, /* Ṁ to M */ - { 0x1E41, 0x6D, 0x00 }, /* ṁ to m */ - { 0x1E56, 0x50, 0x00 }, /* Ṗ to P */ - { 0x1E57, 0x70, 0x00 }, /* ṗ to p */ - { 0x1E60, 0x53, 0x00 }, /* Ṡ to S */ - { 0x1E61, 0x73, 0x00 }, /* ṡ to s */ - { 0x1E6A, 0x54, 0x00 }, /* Ṫ to T */ - { 0x1E6B, 0x74, 0x00 }, /* ṫ to t */ - { 0x1E80, 0x57, 0x00 }, /* Ẁ to W */ - { 0x1E81, 0x77, 0x00 }, /* ẁ to w */ - { 0x1E82, 0x57, 0x00 }, /* Ẃ to W */ - { 0x1E83, 0x77, 0x00 }, /* ẃ to w */ - { 0x1E84, 0x57, 0x00 }, /* Ẅ to W */ - { 0x1E85, 0x77, 0x00 }, /* ẅ to w */ - { 0x1EF2, 0x59, 0x00 }, /* Ỳ to Y */ - { 0x1EF3, 0x79, 0x00 }, /* ỳ to y */ - { 0xFB00, 0x66, 0x66 }, /* ff to ff */ - { 0xFB01, 0x66, 0x69 }, /* fi to fi */ - { 0xFB02, 0x66, 0x6C }, /* fl to fl */ - { 0xFB05, 0x73, 0x74 }, /* ſt to st */ - { 0xFB06, 0x73, 0x74 }, /* st to st */ +static const Transliteration translit[] = { + { 0x00A0, 0x20, 0x00, 0x00, 0x00 }, /*   to */ + { 0x00B5, 0x75, 0x00, 0x00, 0x00 }, /* µ to u */ + { 0x00C0, 0x41, 0x00, 0x00, 0x00 }, /* À to A */ + { 0x00C1, 0x41, 0x00, 0x00, 0x00 }, /* Á to A */ + { 0x00C2, 0x41, 0x00, 0x00, 0x00 }, /*  to A */ + { 0x00C3, 0x41, 0x00, 0x00, 0x00 }, /* à to A */ + { 0x00C4, 0x41, 0x65, 0x00, 0x00 }, /* Ä to Ae */ + { 0x00C5, 0x41, 0x61, 0x00, 0x00 }, /* Å to Aa */ + { 0x00C6, 0x41, 0x45, 0x00, 0x00 }, /* Æ to AE */ + { 0x00C7, 0x43, 0x00, 0x00, 0x00 }, /* Ç to C */ + { 0x00C8, 0x45, 0x00, 0x00, 0x00 }, /* È to E */ + { 0x00C9, 0x45, 0x00, 0x00, 0x00 }, /* É to E */ + { 0x00CA, 0x45, 0x00, 0x00, 0x00 }, /* Ê to E */ + { 0x00CB, 0x45, 0x00, 0x00, 0x00 }, /* Ë to E */ + { 0x00CC, 0x49, 0x00, 0x00, 0x00 }, /* Ì to I */ + { 0x00CD, 0x49, 0x00, 0x00, 0x00 }, /* Í to I */ + { 0x00CE, 0x49, 0x00, 0x00, 0x00 }, /* Î to I */ + { 0x00CF, 0x49, 0x00, 0x00, 0x00 }, /* Ï to I */ + { 0x00D0, 0x44, 0x00, 0x00, 0x00 }, /* Ð to D */ + { 0x00D1, 0x4E, 0x00, 0x00, 0x00 }, /* Ñ to N */ + { 0x00D2, 0x4F, 0x00, 0x00, 0x00 }, /* Ò to O */ + { 0x00D3, 0x4F, 0x00, 0x00, 0x00 }, /* Ó to O */ + { 0x00D4, 0x4F, 0x00, 0x00, 0x00 }, /* Ô to O */ + { 0x00D5, 0x4F, 0x00, 0x00, 0x00 }, /* Õ to O */ + { 0x00D6, 0x4F, 0x65, 0x00, 0x00 }, /* Ö to Oe */ + { 0x00D7, 0x78, 0x00, 0x00, 0x00 }, /* × to x */ + { 0x00D8, 0x4F, 0x00, 0x00, 0x00 }, /* Ø to O */ + { 0x00D9, 0x55, 0x00, 0x00, 0x00 }, /* Ù to U */ + { 0x00DA, 0x55, 0x00, 0x00, 0x00 }, /* Ú to U */ + { 0x00DB, 0x55, 0x00, 0x00, 0x00 }, /* Û to U */ + { 0x00DC, 0x55, 0x65, 0x00, 0x00 }, /* Ü to Ue */ + { 0x00DD, 0x59, 0x00, 0x00, 0x00 }, /* Ý to Y */ + { 0x00DE, 0x54, 0x68, 0x00, 0x00 }, /* Þ to Th */ + { 0x00DF, 0x73, 0x73, 0x00, 0x00 }, /* ß to ss */ + { 0x00E0, 0x61, 0x00, 0x00, 0x00 }, /* à to a */ + { 0x00E1, 0x61, 0x00, 0x00, 0x00 }, /* á to a */ + { 0x00E2, 0x61, 0x00, 0x00, 0x00 }, /* â to a */ + { 0x00E3, 0x61, 0x00, 0x00, 0x00 }, /* ã to a */ + { 0x00E4, 0x61, 0x65, 0x00, 0x00 }, /* ä to ae */ + { 0x00E5, 0x61, 0x61, 0x00, 0x00 }, /* å to aa */ + { 0x00E6, 0x61, 0x65, 0x00, 0x00 }, /* æ to ae */ + { 0x00E7, 0x63, 0x00, 0x00, 0x00 }, /* ç to c */ + { 0x00E8, 0x65, 0x00, 0x00, 0x00 }, /* è to e */ + { 0x00E9, 0x65, 0x00, 0x00, 0x00 }, /* é to e */ + { 0x00EA, 0x65, 0x00, 0x00, 0x00 }, /* ê to e */ + { 0x00EB, 0x65, 0x00, 0x00, 0x00 }, /* ë to e */ + { 0x00EC, 0x69, 0x00, 0x00, 0x00 }, /* ì to i */ + { 0x00ED, 0x69, 0x00, 0x00, 0x00 }, /* í to i */ + { 0x00EE, 0x69, 0x00, 0x00, 0x00 }, /* î to i */ + { 0x00EF, 0x69, 0x00, 0x00, 0x00 }, /* ï to i */ + { 0x00F0, 0x64, 0x00, 0x00, 0x00 }, /* ð to d */ + { 0x00F1, 0x6E, 0x00, 0x00, 0x00 }, /* ñ to n */ + { 0x00F2, 0x6F, 0x00, 0x00, 0x00 }, /* ò to o */ + { 0x00F3, 0x6F, 0x00, 0x00, 0x00 }, /* ó to o */ + { 0x00F4, 0x6F, 0x00, 0x00, 0x00 }, /* ô to o */ + { 0x00F5, 0x6F, 0x00, 0x00, 0x00 }, /* õ to o */ + { 0x00F6, 0x6F, 0x65, 0x00, 0x00 }, /* ö to oe */ + { 0x00F7, 0x3A, 0x00, 0x00, 0x00 }, /* ÷ to : */ + { 0x00F8, 0x6F, 0x00, 0x00, 0x00 }, /* ø to o */ + { 0x00F9, 0x75, 0x00, 0x00, 0x00 }, /* ù to u */ + { 0x00FA, 0x75, 0x00, 0x00, 0x00 }, /* ú to u */ + { 0x00FB, 0x75, 0x00, 0x00, 0x00 }, /* û to u */ + { 0x00FC, 0x75, 0x65, 0x00, 0x00 }, /* ü to ue */ + { 0x00FD, 0x79, 0x00, 0x00, 0x00 }, /* ý to y */ + { 0x00FE, 0x74, 0x68, 0x00, 0x00 }, /* þ to th */ + { 0x00FF, 0x79, 0x00, 0x00, 0x00 }, /* ÿ to y */ + { 0x0100, 0x41, 0x00, 0x00, 0x00 }, /* Ā to A */ + { 0x0101, 0x61, 0x00, 0x00, 0x00 }, /* ā to a */ + { 0x0102, 0x41, 0x00, 0x00, 0x00 }, /* Ă to A */ + { 0x0103, 0x61, 0x00, 0x00, 0x00 }, /* ă to a */ + { 0x0104, 0x41, 0x00, 0x00, 0x00 }, /* Ą to A */ + { 0x0105, 0x61, 0x00, 0x00, 0x00 }, /* ą to a */ + { 0x0106, 0x43, 0x00, 0x00, 0x00 }, /* Ć to C */ + { 0x0107, 0x63, 0x00, 0x00, 0x00 }, /* ć to c */ + { 0x0108, 0x43, 0x68, 0x00, 0x00 }, /* Ĉ to Ch */ + { 0x0109, 0x63, 0x68, 0x00, 0x00 }, /* ĉ to ch */ + { 0x010A, 0x43, 0x00, 0x00, 0x00 }, /* Ċ to C */ + { 0x010B, 0x63, 0x00, 0x00, 0x00 }, /* ċ to c */ + { 0x010C, 0x43, 0x00, 0x00, 0x00 }, /* Č to C */ + { 0x010D, 0x63, 0x00, 0x00, 0x00 }, /* č to c */ + { 0x010E, 0x44, 0x00, 0x00, 0x00 }, /* Ď to D */ + { 0x010F, 0x64, 0x00, 0x00, 0x00 }, /* ď to d */ + { 0x0110, 0x44, 0x00, 0x00, 0x00 }, /* Đ to D */ + { 0x0111, 0x64, 0x00, 0x00, 0x00 }, /* đ to d */ + { 0x0112, 0x45, 0x00, 0x00, 0x00 }, /* Ē to E */ + { 0x0113, 0x65, 0x00, 0x00, 0x00 }, /* ē to e */ + { 0x0114, 0x45, 0x00, 0x00, 0x00 }, /* Ĕ to E */ + { 0x0115, 0x65, 0x00, 0x00, 0x00 }, /* ĕ to e */ + { 0x0116, 0x45, 0x00, 0x00, 0x00 }, /* Ė to E */ + { 0x0117, 0x65, 0x00, 0x00, 0x00 }, /* ė to e */ + { 0x0118, 0x45, 0x00, 0x00, 0x00 }, /* Ę to E */ + { 0x0119, 0x65, 0x00, 0x00, 0x00 }, /* ę to e */ + { 0x011A, 0x45, 0x00, 0x00, 0x00 }, /* Ě to E */ + { 0x011B, 0x65, 0x00, 0x00, 0x00 }, /* ě to e */ + { 0x011C, 0x47, 0x68, 0x00, 0x00 }, /* Ĝ to Gh */ + { 0x011D, 0x67, 0x68, 0x00, 0x00 }, /* ĝ to gh */ + { 0x011E, 0x47, 0x00, 0x00, 0x00 }, /* Ğ to G */ + { 0x011F, 0x67, 0x00, 0x00, 0x00 }, /* ğ to g */ + { 0x0120, 0x47, 0x00, 0x00, 0x00 }, /* Ġ to G */ + { 0x0121, 0x67, 0x00, 0x00, 0x00 }, /* ġ to g */ + { 0x0122, 0x47, 0x00, 0x00, 0x00 }, /* Ģ to G */ + { 0x0123, 0x67, 0x00, 0x00, 0x00 }, /* ģ to g */ + { 0x0124, 0x48, 0x68, 0x00, 0x00 }, /* Ĥ to Hh */ + { 0x0125, 0x68, 0x68, 0x00, 0x00 }, /* ĥ to hh */ + { 0x0126, 0x48, 0x00, 0x00, 0x00 }, /* Ħ to H */ + { 0x0127, 0x68, 0x00, 0x00, 0x00 }, /* ħ to h */ + { 0x0128, 0x49, 0x00, 0x00, 0x00 }, /* Ĩ to I */ + { 0x0129, 0x69, 0x00, 0x00, 0x00 }, /* ĩ to i */ + { 0x012A, 0x49, 0x00, 0x00, 0x00 }, /* Ī to I */ + { 0x012B, 0x69, 0x00, 0x00, 0x00 }, /* ī to i */ + { 0x012C, 0x49, 0x00, 0x00, 0x00 }, /* Ĭ to I */ + { 0x012D, 0x69, 0x00, 0x00, 0x00 }, /* ĭ to i */ + { 0x012E, 0x49, 0x00, 0x00, 0x00 }, /* Į to I */ + { 0x012F, 0x69, 0x00, 0x00, 0x00 }, /* į to i */ + { 0x0130, 0x49, 0x00, 0x00, 0x00 }, /* İ to I */ + { 0x0131, 0x69, 0x00, 0x00, 0x00 }, /* ı to i */ + { 0x0132, 0x49, 0x4A, 0x00, 0x00 }, /* IJ to IJ */ + { 0x0133, 0x69, 0x6A, 0x00, 0x00 }, /* ij to ij */ + { 0x0134, 0x4A, 0x68, 0x00, 0x00 }, /* Ĵ to Jh */ + { 0x0135, 0x6A, 0x68, 0x00, 0x00 }, /* ĵ to jh */ + { 0x0136, 0x4B, 0x00, 0x00, 0x00 }, /* Ķ to K */ + { 0x0137, 0x6B, 0x00, 0x00, 0x00 }, /* ķ to k */ + { 0x0138, 0x6B, 0x00, 0x00, 0x00 }, /* ĸ to k */ + { 0x0139, 0x4C, 0x00, 0x00, 0x00 }, /* Ĺ to L */ + { 0x013A, 0x6C, 0x00, 0x00, 0x00 }, /* ĺ to l */ + { 0x013B, 0x4C, 0x00, 0x00, 0x00 }, /* Ļ to L */ + { 0x013C, 0x6C, 0x00, 0x00, 0x00 }, /* ļ to l */ + { 0x013D, 0x4C, 0x00, 0x00, 0x00 }, /* Ľ to L */ + { 0x013E, 0x6C, 0x00, 0x00, 0x00 }, /* ľ to l */ + { 0x013F, 0x4C, 0x2E, 0x00, 0x00 }, /* Ŀ to L. */ + { 0x0140, 0x6C, 0x2E, 0x00, 0x00 }, /* ŀ to l. */ + { 0x0141, 0x4C, 0x00, 0x00, 0x00 }, /* Ł to L */ + { 0x0142, 0x6C, 0x00, 0x00, 0x00 }, /* ł to l */ + { 0x0143, 0x4E, 0x00, 0x00, 0x00 }, /* Ń to N */ + { 0x0144, 0x6E, 0x00, 0x00, 0x00 }, /* ń to n */ + { 0x0145, 0x4E, 0x00, 0x00, 0x00 }, /* Ņ to N */ + { 0x0146, 0x6E, 0x00, 0x00, 0x00 }, /* ņ to n */ + { 0x0147, 0x4E, 0x00, 0x00, 0x00 }, /* Ň to N */ + { 0x0148, 0x6E, 0x00, 0x00, 0x00 }, /* ň to n */ + { 0x0149, 0x27, 0x6E, 0x00, 0x00 }, /* ʼn to 'n */ + { 0x014A, 0x4E, 0x47, 0x00, 0x00 }, /* Ŋ to NG */ + { 0x014B, 0x6E, 0x67, 0x00, 0x00 }, /* ŋ to ng */ + { 0x014C, 0x4F, 0x00, 0x00, 0x00 }, /* Ō to O */ + { 0x014D, 0x6F, 0x00, 0x00, 0x00 }, /* ō to o */ + { 0x014E, 0x4F, 0x00, 0x00, 0x00 }, /* Ŏ to O */ + { 0x014F, 0x6F, 0x00, 0x00, 0x00 }, /* ŏ to o */ + { 0x0150, 0x4F, 0x00, 0x00, 0x00 }, /* Ő to O */ + { 0x0151, 0x6F, 0x00, 0x00, 0x00 }, /* ő to o */ + { 0x0152, 0x4F, 0x45, 0x00, 0x00 }, /* Œ to OE */ + { 0x0153, 0x6F, 0x65, 0x00, 0x00 }, /* œ to oe */ + { 0x0154, 0x52, 0x00, 0x00, 0x00 }, /* Ŕ to R */ + { 0x0155, 0x72, 0x00, 0x00, 0x00 }, /* ŕ to r */ + { 0x0156, 0x52, 0x00, 0x00, 0x00 }, /* Ŗ to R */ + { 0x0157, 0x72, 0x00, 0x00, 0x00 }, /* ŗ to r */ + { 0x0158, 0x52, 0x00, 0x00, 0x00 }, /* Ř to R */ + { 0x0159, 0x72, 0x00, 0x00, 0x00 }, /* ř to r */ + { 0x015A, 0x53, 0x00, 0x00, 0x00 }, /* Ś to S */ + { 0x015B, 0x73, 0x00, 0x00, 0x00 }, /* ś to s */ + { 0x015C, 0x53, 0x68, 0x00, 0x00 }, /* Ŝ to Sh */ + { 0x015D, 0x73, 0x68, 0x00, 0x00 }, /* ŝ to sh */ + { 0x015E, 0x53, 0x00, 0x00, 0x00 }, /* Ş to S */ + { 0x015F, 0x73, 0x00, 0x00, 0x00 }, /* ş to s */ + { 0x0160, 0x53, 0x00, 0x00, 0x00 }, /* Š to S */ + { 0x0161, 0x73, 0x00, 0x00, 0x00 }, /* š to s */ + { 0x0162, 0x54, 0x00, 0x00, 0x00 }, /* Ţ to T */ + { 0x0163, 0x74, 0x00, 0x00, 0x00 }, /* ţ to t */ + { 0x0164, 0x54, 0x00, 0x00, 0x00 }, /* Ť to T */ + { 0x0165, 0x74, 0x00, 0x00, 0x00 }, /* ť to t */ + { 0x0166, 0x54, 0x00, 0x00, 0x00 }, /* Ŧ to T */ + { 0x0167, 0x74, 0x00, 0x00, 0x00 }, /* ŧ to t */ + { 0x0168, 0x55, 0x00, 0x00, 0x00 }, /* Ũ to U */ + { 0x0169, 0x75, 0x00, 0x00, 0x00 }, /* ũ to u */ + { 0x016A, 0x55, 0x00, 0x00, 0x00 }, /* Ū to U */ + { 0x016B, 0x75, 0x00, 0x00, 0x00 }, /* ū to u */ + { 0x016C, 0x55, 0x00, 0x00, 0x00 }, /* Ŭ to U */ + { 0x016D, 0x75, 0x00, 0x00, 0x00 }, /* ŭ to u */ + { 0x016E, 0x55, 0x00, 0x00, 0x00 }, /* Ů to U */ + { 0x016F, 0x75, 0x00, 0x00, 0x00 }, /* ů to u */ + { 0x0170, 0x55, 0x00, 0x00, 0x00 }, /* Ű to U */ + { 0x0171, 0x75, 0x00, 0x00, 0x00 }, /* ű to u */ + { 0x0172, 0x55, 0x00, 0x00, 0x00 }, /* Ų to U */ + { 0x0173, 0x75, 0x00, 0x00, 0x00 }, /* ų to u */ + { 0x0174, 0x57, 0x00, 0x00, 0x00 }, /* Ŵ to W */ + { 0x0175, 0x77, 0x00, 0x00, 0x00 }, /* ŵ to w */ + { 0x0176, 0x59, 0x00, 0x00, 0x00 }, /* Ŷ to Y */ + { 0x0177, 0x79, 0x00, 0x00, 0x00 }, /* ŷ to y */ + { 0x0178, 0x59, 0x00, 0x00, 0x00 }, /* Ÿ to Y */ + { 0x0179, 0x5A, 0x00, 0x00, 0x00 }, /* Ź to Z */ + { 0x017A, 0x7A, 0x00, 0x00, 0x00 }, /* ź to z */ + { 0x017B, 0x5A, 0x00, 0x00, 0x00 }, /* Ż to Z */ + { 0x017C, 0x7A, 0x00, 0x00, 0x00 }, /* ż to z */ + { 0x017D, 0x5A, 0x00, 0x00, 0x00 }, /* Ž to Z */ + { 0x017E, 0x7A, 0x00, 0x00, 0x00 }, /* ž to z */ + { 0x017F, 0x73, 0x00, 0x00, 0x00 }, /* ſ to s */ + { 0x0192, 0x66, 0x00, 0x00, 0x00 }, /* ƒ to f */ + { 0x0218, 0x53, 0x00, 0x00, 0x00 }, /* Ș to S */ + { 0x0219, 0x73, 0x00, 0x00, 0x00 }, /* ș to s */ + { 0x021A, 0x54, 0x00, 0x00, 0x00 }, /* Ț to T */ + { 0x021B, 0x74, 0x00, 0x00, 0x00 }, /* ț to t */ + { 0x0386, 0x41, 0x00, 0x00, 0x00 }, /* Ά to A */ + { 0x0388, 0x45, 0x00, 0x00, 0x00 }, /* Έ to E */ + { 0x0389, 0x49, 0x00, 0x00, 0x00 }, /* Ή to I */ + { 0x038A, 0x49, 0x00, 0x00, 0x00 }, /* Ί to I */ + { 0x038C, 0x4f, 0x00, 0x00, 0x00 }, /* Ό to O */ + { 0x038E, 0x59, 0x00, 0x00, 0x00 }, /* Ύ to Y */ + { 0x038F, 0x4f, 0x00, 0x00, 0x00 }, /* Ώ to O */ + { 0x0390, 0x69, 0x00, 0x00, 0x00 }, /* ΐ to i */ + { 0x0391, 0x41, 0x00, 0x00, 0x00 }, /* Α to A */ + { 0x0392, 0x42, 0x00, 0x00, 0x00 }, /* Β to B */ + { 0x0393, 0x47, 0x00, 0x00, 0x00 }, /* Γ to G */ + { 0x0394, 0x44, 0x00, 0x00, 0x00 }, /* Δ to D */ + { 0x0395, 0x45, 0x00, 0x00, 0x00 }, /* Ε to E */ + { 0x0396, 0x5a, 0x00, 0x00, 0x00 }, /* Ζ to Z */ + { 0x0397, 0x49, 0x00, 0x00, 0x00 }, /* Η to I */ + { 0x0398, 0x54, 0x68, 0x00, 0x00 }, /* Θ to Th */ + { 0x0399, 0x49, 0x00, 0x00, 0x00 }, /* Ι to I */ + { 0x039A, 0x4b, 0x00, 0x00, 0x00 }, /* Κ to K */ + { 0x039B, 0x4c, 0x00, 0x00, 0x00 }, /* Λ to L */ + { 0x039C, 0x4d, 0x00, 0x00, 0x00 }, /* Μ to M */ + { 0x039D, 0x4e, 0x00, 0x00, 0x00 }, /* Ν to N */ + { 0x039E, 0x58, 0x00, 0x00, 0x00 }, /* Ξ to X */ + { 0x039F, 0x4f, 0x00, 0x00, 0x00 }, /* Ο to O */ + { 0x03A0, 0x50, 0x00, 0x00, 0x00 }, /* Π to P */ + { 0x03A1, 0x52, 0x00, 0x00, 0x00 }, /* Ρ to R */ + { 0x03A3, 0x53, 0x00, 0x00, 0x00 }, /* Σ to S */ + { 0x03A4, 0x54, 0x00, 0x00, 0x00 }, /* Τ to T */ + { 0x03A5, 0x59, 0x00, 0x00, 0x00 }, /* Υ to Y */ + { 0x03A6, 0x46, 0x00, 0x00, 0x00 }, /* Φ to F */ + { 0x03A7, 0x43, 0x68, 0x00, 0x00 }, /* Χ to Ch */ + { 0x03A8, 0x50, 0x73, 0x00, 0x00 }, /* Ψ to Ps */ + { 0x03A9, 0x4f, 0x00, 0x00, 0x00 }, /* Ω to O */ + { 0x03AA, 0x49, 0x00, 0x00, 0x00 }, /* Ϊ to I */ + { 0x03AB, 0x59, 0x00, 0x00, 0x00 }, /* Ϋ to Y */ + { 0x03AC, 0x61, 0x00, 0x00, 0x00 }, /* ά to a */ + { 0x03AD, 0x65, 0x00, 0x00, 0x00 }, /* έ to e */ + { 0x03AE, 0x69, 0x00, 0x00, 0x00 }, /* ή to i */ + { 0x03AF, 0x69, 0x00, 0x00, 0x00 }, /* ί to i */ + { 0x03B1, 0x61, 0x00, 0x00, 0x00 }, /* α to a */ + { 0x03B2, 0x62, 0x00, 0x00, 0x00 }, /* β to b */ + { 0x03B3, 0x67, 0x00, 0x00, 0x00 }, /* γ to g */ + { 0x03B4, 0x64, 0x00, 0x00, 0x00 }, /* δ to d */ + { 0x03B5, 0x65, 0x00, 0x00, 0x00 }, /* ε to e */ + { 0x03B6, 0x7a, 0x00, 0x00, 0x00 }, /* ζ to z */ + { 0x03B7, 0x69, 0x00, 0x00, 0x00 }, /* η to i */ + { 0x03B8, 0x74, 0x68, 0x00, 0x00 }, /* θ to th */ + { 0x03B9, 0x69, 0x00, 0x00, 0x00 }, /* ι to i */ + { 0x03BA, 0x6b, 0x00, 0x00, 0x00 }, /* κ to k */ + { 0x03BB, 0x6c, 0x00, 0x00, 0x00 }, /* λ to l */ + { 0x03BC, 0x6d, 0x00, 0x00, 0x00 }, /* μ to m */ + { 0x03BD, 0x6e, 0x00, 0x00, 0x00 }, /* ν to n */ + { 0x03BE, 0x78, 0x00, 0x00, 0x00 }, /* ξ to x */ + { 0x03BF, 0x6f, 0x00, 0x00, 0x00 }, /* ο to o */ + { 0x03C0, 0x70, 0x00, 0x00, 0x00 }, /* π to p */ + { 0x03C1, 0x72, 0x00, 0x00, 0x00 }, /* ρ to r */ + { 0x03C3, 0x73, 0x00, 0x00, 0x00 }, /* σ to s */ + { 0x03C4, 0x74, 0x00, 0x00, 0x00 }, /* τ to t */ + { 0x03C5, 0x79, 0x00, 0x00, 0x00 }, /* υ to y */ + { 0x03C6, 0x66, 0x00, 0x00, 0x00 }, /* φ to f */ + { 0x03C7, 0x63, 0x68, 0x00, 0x00 }, /* χ to ch */ + { 0x03C8, 0x70, 0x73, 0x00, 0x00 }, /* ψ to ps */ + { 0x03C9, 0x6f, 0x00, 0x00, 0x00 }, /* ω to o */ + { 0x03CA, 0x69, 0x00, 0x00, 0x00 }, /* ϊ to i */ + { 0x03CB, 0x79, 0x00, 0x00, 0x00 }, /* ϋ to y */ + { 0x03CC, 0x6f, 0x00, 0x00, 0x00 }, /* ό to o */ + { 0x03CD, 0x79, 0x00, 0x00, 0x00 }, /* ύ to y */ + { 0x03CE, 0x69, 0x00, 0x00, 0x00 }, /* ώ to i */ + { 0x0400, 0x45, 0x00, 0x00, 0x00 }, /* Ѐ to E */ + { 0x0401, 0x45, 0x00, 0x00, 0x00 }, /* Ё to E */ + { 0x0402, 0x44, 0x00, 0x00, 0x00 }, /* Ђ to D */ + { 0x0403, 0x47, 0x00, 0x00, 0x00 }, /* Ѓ to G */ + { 0x0404, 0x45, 0x00, 0x00, 0x00 }, /* Є to E */ + { 0x0405, 0x5a, 0x00, 0x00, 0x00 }, /* Ѕ to Z */ + { 0x0406, 0x49, 0x00, 0x00, 0x00 }, /* І to I */ + { 0x0407, 0x49, 0x00, 0x00, 0x00 }, /* Ї to I */ + { 0x0408, 0x4a, 0x00, 0x00, 0x00 }, /* Ј to J */ + { 0x0409, 0x49, 0x00, 0x00, 0x00 }, /* Љ to I */ + { 0x040A, 0x4e, 0x00, 0x00, 0x00 }, /* Њ to N */ + { 0x040B, 0x44, 0x00, 0x00, 0x00 }, /* Ћ to D */ + { 0x040C, 0x4b, 0x00, 0x00, 0x00 }, /* Ќ to K */ + { 0x040D, 0x49, 0x00, 0x00, 0x00 }, /* Ѝ to I */ + { 0x040E, 0x55, 0x00, 0x00, 0x00 }, /* Ў to U */ + { 0x040F, 0x44, 0x00, 0x00, 0x00 }, /* Џ to D */ + { 0x0410, 0x41, 0x00, 0x00, 0x00 }, /* А to A */ + { 0x0411, 0x42, 0x00, 0x00, 0x00 }, /* Б to B */ + { 0x0412, 0x56, 0x00, 0x00, 0x00 }, /* В to V */ + { 0x0413, 0x47, 0x00, 0x00, 0x00 }, /* Г to G */ + { 0x0414, 0x44, 0x00, 0x00, 0x00 }, /* Д to D */ + { 0x0415, 0x45, 0x00, 0x00, 0x00 }, /* Е to E */ + { 0x0416, 0x5a, 0x68, 0x00, 0x00 }, /* Ж to Zh */ + { 0x0417, 0x5a, 0x00, 0x00, 0x00 }, /* З to Z */ + { 0x0418, 0x49, 0x00, 0x00, 0x00 }, /* И to I */ + { 0x0419, 0x49, 0x00, 0x00, 0x00 }, /* Й to I */ + { 0x041A, 0x4b, 0x00, 0x00, 0x00 }, /* К to K */ + { 0x041B, 0x4c, 0x00, 0x00, 0x00 }, /* Л to L */ + { 0x041C, 0x4d, 0x00, 0x00, 0x00 }, /* М to M */ + { 0x041D, 0x4e, 0x00, 0x00, 0x00 }, /* Н to N */ + { 0x041E, 0x4f, 0x00, 0x00, 0x00 }, /* О to O */ + { 0x041F, 0x50, 0x00, 0x00, 0x00 }, /* П to P */ + { 0x0420, 0x52, 0x00, 0x00, 0x00 }, /* Р to R */ + { 0x0421, 0x53, 0x00, 0x00, 0x00 }, /* С to S */ + { 0x0422, 0x54, 0x00, 0x00, 0x00 }, /* Т to T */ + { 0x0423, 0x55, 0x00, 0x00, 0x00 }, /* У to U */ + { 0x0424, 0x46, 0x00, 0x00, 0x00 }, /* Ф to F */ + { 0x0425, 0x4b, 0x68, 0x00, 0x00 }, /* Х to Kh */ + { 0x0426, 0x54, 0x63, 0x00, 0x00 }, /* Ц to Tc */ + { 0x0427, 0x43, 0x68, 0x00, 0x00 }, /* Ч to Ch */ + { 0x0428, 0x53, 0x68, 0x00, 0x00 }, /* Ш to Sh */ + { 0x0429, 0x53, 0x68, 0x63, 0x68 }, /* Щ to Shch */ + { 0x042A, 0x61, 0x00, 0x00, 0x00 }, /* to A */ + { 0x042B, 0x59, 0x00, 0x00, 0x00 }, /* Ы to Y */ + { 0x042C, 0x59, 0x00, 0x00, 0x00 }, /* to Y */ + { 0x042D, 0x45, 0x00, 0x00, 0x00 }, /* Э to E */ + { 0x042E, 0x49, 0x75, 0x00, 0x00 }, /* Ю to Iu */ + { 0x042F, 0x49, 0x61, 0x00, 0x00 }, /* Я to Ia */ + { 0x0430, 0x61, 0x00, 0x00, 0x00 }, /* а to a */ + { 0x0431, 0x62, 0x00, 0x00, 0x00 }, /* б to b */ + { 0x0432, 0x76, 0x00, 0x00, 0x00 }, /* в to v */ + { 0x0433, 0x67, 0x00, 0x00, 0x00 }, /* г to g */ + { 0x0434, 0x64, 0x00, 0x00, 0x00 }, /* д to d */ + { 0x0435, 0x65, 0x00, 0x00, 0x00 }, /* е to e */ + { 0x0436, 0x7a, 0x68, 0x00, 0x00 }, /* ж to zh */ + { 0x0437, 0x7a, 0x00, 0x00, 0x00 }, /* з to z */ + { 0x0438, 0x69, 0x00, 0x00, 0x00 }, /* и to i */ + { 0x0439, 0x69, 0x00, 0x00, 0x00 }, /* й to i */ + { 0x043A, 0x6b, 0x00, 0x00, 0x00 }, /* к to k */ + { 0x043B, 0x6c, 0x00, 0x00, 0x00 }, /* л to l */ + { 0x043C, 0x6d, 0x00, 0x00, 0x00 }, /* м to m */ + { 0x043D, 0x6e, 0x00, 0x00, 0x00 }, /* н to n */ + { 0x043E, 0x6f, 0x00, 0x00, 0x00 }, /* о to o */ + { 0x043F, 0x70, 0x00, 0x00, 0x00 }, /* п to p */ + { 0x0440, 0x72, 0x00, 0x00, 0x00 }, /* р to r */ + { 0x0441, 0x73, 0x00, 0x00, 0x00 }, /* с to s */ + { 0x0442, 0x74, 0x00, 0x00, 0x00 }, /* т to t */ + { 0x0443, 0x75, 0x00, 0x00, 0x00 }, /* у to u */ + { 0x0444, 0x66, 0x00, 0x00, 0x00 }, /* ф to f */ + { 0x0445, 0x6b, 0x68, 0x00, 0x00 }, /* х to kh */ + { 0x0446, 0x74, 0x63, 0x00, 0x00 }, /* ц to tc */ + { 0x0447, 0x63, 0x68, 0x00, 0x00 }, /* ч to ch */ + { 0x0448, 0x73, 0x68, 0x00, 0x00 }, /* ш to sh */ + { 0x0449, 0x73, 0x68, 0x63, 0x68 }, /* щ to shch */ + { 0x044A, 0x61, 0x00, 0x00, 0x00 }, /* to a */ + { 0x044B, 0x79, 0x00, 0x00, 0x00 }, /* ы to y */ + { 0x044C, 0x79, 0x00, 0x00, 0x00 }, /* to y */ + { 0x044D, 0x65, 0x00, 0x00, 0x00 }, /* э to e */ + { 0x044E, 0x69, 0x75, 0x00, 0x00 }, /* ю to iu */ + { 0x044F, 0x69, 0x61, 0x00, 0x00 }, /* я to ia */ + { 0x0450, 0x65, 0x00, 0x00, 0x00 }, /* ѐ to e */ + { 0x0451, 0x65, 0x00, 0x00, 0x00 }, /* ё to e */ + { 0x0452, 0x64, 0x00, 0x00, 0x00 }, /* ђ to d */ + { 0x0453, 0x67, 0x00, 0x00, 0x00 }, /* ѓ to g */ + { 0x0454, 0x65, 0x00, 0x00, 0x00 }, /* є to e */ + { 0x0455, 0x7a, 0x00, 0x00, 0x00 }, /* ѕ to z */ + { 0x0456, 0x69, 0x00, 0x00, 0x00 }, /* і to i */ + { 0x0457, 0x69, 0x00, 0x00, 0x00 }, /* ї to i */ + { 0x0458, 0x6a, 0x00, 0x00, 0x00 }, /* ј to j */ + { 0x0459, 0x69, 0x00, 0x00, 0x00 }, /* љ to i */ + { 0x045A, 0x6e, 0x00, 0x00, 0x00 }, /* њ to n */ + { 0x045B, 0x64, 0x00, 0x00, 0x00 }, /* ћ to d */ + { 0x045C, 0x6b, 0x00, 0x00, 0x00 }, /* ќ to k */ + { 0x045D, 0x69, 0x00, 0x00, 0x00 }, /* ѝ to i */ + { 0x045E, 0x75, 0x00, 0x00, 0x00 }, /* ў to u */ + { 0x045F, 0x64, 0x00, 0x00, 0x00 }, /* џ to d */ + { 0x1E02, 0x42, 0x00, 0x00, 0x00 }, /* Ḃ to B */ + { 0x1E03, 0x62, 0x00, 0x00, 0x00 }, /* ḃ to b */ + { 0x1E0A, 0x44, 0x00, 0x00, 0x00 }, /* Ḋ to D */ + { 0x1E0B, 0x64, 0x00, 0x00, 0x00 }, /* ḋ to d */ + { 0x1E1E, 0x46, 0x00, 0x00, 0x00 }, /* Ḟ to F */ + { 0x1E1F, 0x66, 0x00, 0x00, 0x00 }, /* ḟ to f */ + { 0x1E40, 0x4D, 0x00, 0x00, 0x00 }, /* Ṁ to M */ + { 0x1E41, 0x6D, 0x00, 0x00, 0x00 }, /* ṁ to m */ + { 0x1E56, 0x50, 0x00, 0x00, 0x00 }, /* Ṗ to P */ + { 0x1E57, 0x70, 0x00, 0x00, 0x00 }, /* ṗ to p */ + { 0x1E60, 0x53, 0x00, 0x00, 0x00 }, /* Ṡ to S */ + { 0x1E61, 0x73, 0x00, 0x00, 0x00 }, /* ṡ to s */ + { 0x1E6A, 0x54, 0x00, 0x00, 0x00 }, /* Ṫ to T */ + { 0x1E6B, 0x74, 0x00, 0x00, 0x00 }, /* ṫ to t */ + { 0x1E80, 0x57, 0x00, 0x00, 0x00 }, /* Ẁ to W */ + { 0x1E81, 0x77, 0x00, 0x00, 0x00 }, /* ẁ to w */ + { 0x1E82, 0x57, 0x00, 0x00, 0x00 }, /* Ẃ to W */ + { 0x1E83, 0x77, 0x00, 0x00, 0x00 }, /* ẃ to w */ + { 0x1E84, 0x57, 0x00, 0x00, 0x00 }, /* Ẅ to W */ + { 0x1E85, 0x77, 0x00, 0x00, 0x00 }, /* ẅ to w */ + { 0x1EF2, 0x59, 0x00, 0x00, 0x00 }, /* Ỳ to Y */ + { 0x1EF3, 0x79, 0x00, 0x00, 0x00 }, /* ỳ to y */ + { 0xFB00, 0x66, 0x66, 0x00, 0x00 }, /* ff to ff */ + { 0xFB01, 0x66, 0x69, 0x00, 0x00 }, /* fi to fi */ + { 0xFB02, 0x66, 0x6C, 0x00, 0x00 }, /* fl to fl */ + { 0xFB05, 0x73, 0x74, 0x00, 0x00 }, /* ſt to st */ + { 0xFB06, 0x73, 0x74, 0x00, 0x00 }, /* st to st */ }; +static const Transliteration *spellfixFindTranslit(int c, int *pxTop){ + *pxTop = (sizeof(translit)/sizeof(translit[0])) - 1; + return translit; +} + /* ** Convert the input string from UTF-8 into pure ASCII by converting ** all non-ASCII characters to some combination of characters in the @@ -1607,7 +1711,11 @@ static const struct { ** should be freed by the caller. */ static unsigned char *transliterate(const unsigned char *zIn, int nIn){ +#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS + unsigned char *zOut = sqlite3_malloc64( nIn*5 + 1 ); +#else unsigned char *zOut = sqlite3_malloc64( nIn*4 + 1 ); +#endif int c, sz, nOut; if( zOut==0 ) return 0; nOut = 0; @@ -1619,23 +1727,29 @@ static unsigned char *transliterate(const unsigned char *zIn, int nIn){ zOut[nOut++] = (unsigned char)c; }else{ int xTop, xBtm, x; - xTop = sizeof(translit)/sizeof(translit[0]) - 1; + const Transliteration *tbl = spellfixFindTranslit(c, &xTop); xBtm = 0; while( xTop>=xBtm ){ x = (xTop + xBtm)/2; - if( translit[x].cFrom==c ){ - zOut[nOut++] = translit[x].cTo0; - if( translit[x].cTo1 ){ - zOut[nOut++] = translit[x].cTo1; - /* Add an extra "ch" after the "sh" for Щ and щ */ - if( c==0x0429 || c== 0x0449 ){ - zOut[nOut++] = 'c'; - zOut[nOut++] = 'h'; + if( tbl[x].cFrom==c ){ + zOut[nOut++] = tbl[x].cTo0; + if( tbl[x].cTo1 ){ + zOut[nOut++] = tbl[x].cTo1; + if( tbl[x].cTo2 ){ + zOut[nOut++] = tbl[x].cTo2; + if( tbl[x].cTo3 ){ + zOut[nOut++] = tbl[x].cTo3; +#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS + if( tbl[x].cTo4 ){ + zOut[nOut++] = tbl[x].cTo4; + } +#endif /* SQLITE_SPELLFIX_5BYTE_MAPPINGS */ + } } } c = 0; break; - }else if( translit[x].cFrom>c ){ + }else if( tbl[x].cFrom>c ){ xTop = x-1; }else{ xBtm = x+1; @@ -1666,15 +1780,22 @@ static int translen_to_charlen(const char *zIn, int nIn, int nTrans){ nOut++; if( c>=128 ){ int xTop, xBtm, x; - xTop = sizeof(translit)/sizeof(translit[0]) - 1; + const Transliteration *tbl = spellfixFindTranslit(c, &xTop); xBtm = 0; while( xTop>=xBtm ){ x = (xTop + xBtm)/2; - if( translit[x].cFrom==c ){ - if( translit[x].cTo1 ) nOut++; - if( c==0x0429 || c== 0x0449 ) nOut += 2; + if( tbl[x].cFrom==c ){ + if( tbl[x].cTo1 ){ + nOut++; + if( tbl[x].cTo2 ){ + nOut++; + if( tbl[x].cTo3 ){ + nOut++; + } + } + } break; - }else if( translit[x].cFrom>c ){ + }else if( tbl[x].cFrom>c ){ xTop = x-1; }else{ xBtm = x+1; @@ -2474,7 +2595,7 @@ static int spellfix1FilterForMatch( nPattern = (int)strlen(zPattern); if( zPattern[nPattern-1]=='*' ) nPattern--; zSql = sqlite3_mprintf( - "SELECT id, word, rank, k1" + "SELECT id, word, rank, coalesce(k1,word)" " FROM \"%w\".\"%w_vocab\"" " WHERE langid=%d AND k2>=?1 AND k2zDbName, p->zTableName, iLang @@ -2808,17 +2929,17 @@ static int spellfix1Update( if( sqlite3_value_type(argv[1])==SQLITE_NULL ){ spellfix1DbExec(&rc, db, "INSERT INTO \"%w\".\"%w_vocab\"(rank,langid,word,k1,k2) " - "VALUES(%d,%d,%Q,%Q,%Q)", + "VALUES(%d,%d,%Q,nullif(%Q,%Q),%Q)", p->zDbName, p->zTableName, - iRank, iLang, zWord, zK1, zK2 + iRank, iLang, zWord, zK1, zWord, zK2 ); }else{ newRowid = sqlite3_value_int64(argv[1]); spellfix1DbExec(&rc, db, "INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) " - "VALUES(%lld,%d,%d,%Q,%Q,%Q)", + "VALUES(%lld,%d,%d,%Q,nullif(%Q,%Q),%Q)", zConflict, p->zDbName, p->zTableName, - newRowid, iRank, iLang, zWord, zK1, zK2 + newRowid, iRank, iLang, zWord, zK1, zWord, zK2 ); } *pRowid = sqlite3_last_insert_rowid(db); @@ -2827,9 +2948,9 @@ static int spellfix1Update( newRowid = *pRowid = sqlite3_value_int64(argv[1]); spellfix1DbExec(&rc, db, "UPDATE OR %s \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d," - " word=%Q, k1=%Q, k2=%Q WHERE id=%lld", + " word=%Q, k1=nullif(%Q,%Q), k2=%Q WHERE id=%lld", zConflict, p->zDbName, p->zTableName, newRowid, iRank, iLang, - zWord, zK1, zK2, rowid + zWord, zK1, zWord, zK2, rowid ); } sqlite3_free(zK1); @@ -2895,18 +3016,22 @@ static sqlite3_module spellfix1Module = { static int spellfix1Register(sqlite3 *db){ int rc = SQLITE_OK; int i; - rc = sqlite3_create_function(db, "spellfix1_translit", 1, SQLITE_UTF8, 0, - transliterateSqlFunc, 0, 0); + rc = sqlite3_create_function(db, "spellfix1_translit", 1, + SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, + transliterateSqlFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "spellfix1_editdist", 2, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "spellfix1_editdist", 2, + SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, editdistSqlFunc, 0, 0); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "spellfix1_phonehash", 1, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "spellfix1_phonehash", 1, + SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, phoneticHashSqlFunc, 0, 0); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "spellfix1_scriptcode", 1, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "spellfix1_scriptcode", 1, + SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, scriptCodeSqlFunc, 0, 0); } if( rc==SQLITE_OK ){ diff --git a/ext/misc/sqlar.c b/ext/misc/sqlar.c new file mode 100644 index 0000000000..e812d70c99 --- /dev/null +++ b/ext/misc/sqlar.c @@ -0,0 +1,121 @@ +/* +** 2017-12-17 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** Utility functions sqlar_compress() and sqlar_uncompress(). Useful +** for working with sqlar archives and used by the shell tool's built-in +** sqlar support. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include + +/* +** Implementation of the "sqlar_compress(X)" SQL function. +** +** If the type of X is SQLITE_BLOB, and compressing that blob using +** zlib utility function compress() yields a smaller blob, return the +** compressed blob. Otherwise, return a copy of X. +** +** SQLar uses the "zlib format" for compressed content. The zlib format +** contains a two-byte identification header and a four-byte checksum at +** the end. This is different from ZIP which uses the raw deflate format. +** +** Future enhancements to SQLar might add support for new compression formats. +** If so, those new formats will be identified by alternative headers in the +** compressed data. +*/ +static void sqlarCompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ + const Bytef *pData = sqlite3_value_blob(argv[0]); + uLong nData = sqlite3_value_bytes(argv[0]); + uLongf nOut = compressBound(nData); + Bytef *pOut; + + pOut = (Bytef*)sqlite3_malloc(nOut); + if( pOut==0 ){ + sqlite3_result_error_nomem(context); + return; + }else{ + if( Z_OK!=compress(pOut, &nOut, pData, nData) ){ + sqlite3_result_error(context, "error in compress()", -1); + }else if( nOut +#include + +/* templatevtab_vtab is a subclass of sqlite3_vtab which is +** underlying representation of the virtual table +*/ +typedef struct templatevtab_vtab templatevtab_vtab; +struct templatevtab_vtab { + sqlite3_vtab base; /* Base class - must be first */ + /* Add new fields here, as necessary */ +}; + +/* templatevtab_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct templatevtab_cursor templatevtab_cursor; +struct templatevtab_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + /* Insert new fields here. For this templatevtab we only keep track + ** of the rowid */ + sqlite3_int64 iRowid; /* The rowid */ +}; + +/* +** The templatevtabConnect() method is invoked to create a new +** template virtual table. +** +** Think of this routine as the constructor for templatevtab_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the templatevtab_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against the virtual table will look like. +*/ +static int templatevtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + templatevtab_vtab *pNew; + int rc; + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(a,b)" + ); + /* For convenience, define symbolic names for the index to each column. */ +#define TEMPLATEVTAB_A 0 +#define TEMPLATEVTAB_B 1 + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; +} + +/* +** This method is the destructor for templatevtab_vtab objects. +*/ +static int templatevtabDisconnect(sqlite3_vtab *pVtab){ + templatevtab_vtab *p = (templatevtab_vtab*)pVtab; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Constructor for a new templatevtab_cursor object. +*/ +static int templatevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + templatevtab_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Destructor for a templatevtab_cursor. +*/ +static int templatevtabClose(sqlite3_vtab_cursor *cur){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + sqlite3_free(pCur); + return SQLITE_OK; +} + + +/* +** Advance a templatevtab_cursor to its next row of output. +*/ +static int templatevtabNext(sqlite3_vtab_cursor *cur){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + pCur->iRowid++; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the templatevtab_cursor +** is currently pointing. +*/ +static int templatevtabColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + switch( i ){ + case TEMPLATEVTAB_A: + sqlite3_result_int(ctx, 1000 + pCur->iRowid); + break; + default: + assert( i==TEMPLATEVTAB_B ); + sqlite3_result_int(ctx, 2000 + pCur->iRowid); + break; + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int templatevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int templatevtabEof(sqlite3_vtab_cursor *cur){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + return pCur->iRowid>=10; +} + +/* +** This method is called to "rewind" the templatevtab_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to templatevtabColumn() or templatevtabRowid() or +** templatevtabEof(). +*/ +static int templatevtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + templatevtab_cursor *pCur = (templatevtab_cursor *)pVtabCursor; + pCur->iRowid = 1; + return SQLITE_OK; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +*/ +static int templatevtabBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + pIdxInfo->estimatedCost = (double)10; + pIdxInfo->estimatedRows = 10; + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** virtual table. +*/ +static sqlite3_module templatevtabModule = { + /* iVersion */ 0, + /* xCreate */ 0, + /* xConnect */ templatevtabConnect, + /* xBestIndex */ templatevtabBestIndex, + /* xDisconnect */ templatevtabDisconnect, + /* xDestroy */ 0, + /* xOpen */ templatevtabOpen, + /* xClose */ templatevtabClose, + /* xFilter */ templatevtabFilter, + /* xNext */ templatevtabNext, + /* xEof */ templatevtabEof, + /* xColumn */ templatevtabColumn, + /* xRowid */ templatevtabRowid, + /* xUpdate */ 0, + /* xBegin */ 0, + /* xSync */ 0, + /* xCommit */ 0, + /* xRollback */ 0, + /* xFindMethod */ 0, + /* xRename */ 0, + /* xSavepoint */ 0, + /* xRelease */ 0, + /* xRollbackTo */ 0 +}; + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_templatevtab_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + rc = sqlite3_create_module(db, "templatevtab", &templatevtabModule, 0); + return rc; +} diff --git a/ext/misc/unionvtab.c b/ext/misc/unionvtab.c index fc87915b38..94a5c8f013 100644 --- a/ext/misc/unionvtab.c +++ b/ext/misc/unionvtab.c @@ -56,6 +56,8 @@ ** ** SWARMVTAB ** +** LEGACY SYNTAX: +** ** A "swarmvtab" virtual table is created similarly to a unionvtab table: ** ** CREATE VIRTUAL TABLE @@ -66,13 +68,78 @@ ** the database file containing the source table. The option ** is optional. If included, it is the name of an application-defined ** SQL function that is invoked with the URI of the file, if the file -** does not already exist on disk. +** does not already exist on disk when required by swarmvtab. +** +** NEW SYNTAX: +** +** Using the new syntax, a swarmvtab table is created with: +** +** CREATE VIRTUAL TABLE USING swarmvtab( +** [, ] +** ); +** +** where valid are: +** +** missing= +** openclose= +** maxopen= +** = +** +** The must return the same 4 columns as for a swarmvtab +** table in legacy mode. However, it may also return a 5th column - the +** "context" column. The text value returned in this column is not used +** at all by the swarmvtab implementation, except that it is passed as +** an additional argument to the two UDF functions that may be invoked +** (see below). +** +** The "missing" option, if present, specifies the name of an SQL UDF +** function to be invoked if a database file is not already present on +** disk when required by swarmvtab. If the did not provide +** a context column, it is invoked as: +** +** SELECT (); +** +** Or, if there was a context column: +** +** SELECT (, ); +** +** The "openclose" option may also specify a UDF function. This function +** is invoked right before swarmvtab opens a database, and right after +** it closes one. The first argument - or first two arguments, if +** supplied the context column - is the same as for +** the "missing" UDF. Following this, the UDF is passed integer value +** 0 before a db is opened, and 1 right after it is closed. If both +** a missing and openclose UDF is supplied, the application should expect +** the following sequence of calls (for a single database): +** +** SELECT (, , 0); +** if( db not already on disk ){ +** SELECT (, ); +** } +** ... swarmvtab uses database ... +** SELECT (, , 1); +** +** The "maxopen" option is used to configure the maximum number of +** database files swarmvtab will hold open simultaneously (default 9). +** +** If an option name begins with a ":" character, then it is assumed +** to be an SQL parameter. In this case, the specified text value is +** bound to the same variable of the before it is +** executed. It is an error of the named SQL parameter does not exist. +** For example: +** +** CREATE VIRTUAL TABLE swarm USING swarmvtab( +** 'SELECT :path || localfile, tbl, min, max FROM swarmdir', +** :path='/home/user/databases/' +** missing='missing_func' +** ); */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include #include +#include #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -128,6 +195,7 @@ struct UnionSrc { /* Fields used by swarmvtab only */ char *zFile; /* Database file containing table zTab */ + char *zContext; /* Context string, if any */ int nUser; /* Current number of users */ sqlite3 *db; /* Database handle */ UnionSrc *pNextClosable; /* Next in list of closable sources */ @@ -145,8 +213,11 @@ struct UnionTab { UnionSrc *aSrc; /* Array of source tables, sorted by rowid */ /* Used by swarmvtab only */ + int bHasContext; /* Has context strings */ char *zSourceStr; /* Expected unionSourceToStr() value */ - char *zNotFoundCallback; /* UDF to invoke if file not found on open */ + sqlite3_stmt *pNotFound; /* UDF to invoke if file not found on open */ + sqlite3_stmt *pOpenClose; /* UDF to invoke on open and close */ + UnionSrc *pClosable; /* First in list of closable sources */ int nOpen; /* Current number of open sources */ int nMaxOpen; /* Maximum number of open sources */ @@ -351,6 +422,39 @@ static void unionFinalize(int *pRc, sqlite3_stmt *pStmt, char **pzErr){ } } +/* +** If an "openclose" UDF was supplied when this virtual table was created, +** invoke it now. The first argument passed is the name of the database +** file for source pSrc. The second is integer value bClose. +** +** If successful, return SQLITE_OK. Otherwise an SQLite error code. In this +** case if argument pzErr is not NULL, also set (*pzErr) to an English +** language error message. The caller is responsible for eventually freeing +** any error message using sqlite3_free(). +*/ +static int unionInvokeOpenClose( + UnionTab *pTab, + UnionSrc *pSrc, + int bClose, + char **pzErr +){ + int rc = SQLITE_OK; + if( pTab->pOpenClose ){ + sqlite3_bind_text(pTab->pOpenClose, 1, pSrc->zFile, -1, SQLITE_STATIC); + if( pTab->bHasContext ){ + sqlite3_bind_text(pTab->pOpenClose, 2, pSrc->zContext, -1, SQLITE_STATIC); + } + sqlite3_bind_int(pTab->pOpenClose, 2+pTab->bHasContext, bClose); + sqlite3_step(pTab->pOpenClose); + if( SQLITE_OK!=(rc = sqlite3_reset(pTab->pOpenClose)) ){ + if( pzErr ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); + } + } + } + return rc; +} + /* ** This function is a no-op for unionvtab. For swarmvtab, it attempts to ** close open database files until at most nMax are open. An SQLite error @@ -358,13 +462,16 @@ static void unionFinalize(int *pRc, sqlite3_stmt *pStmt, char **pzErr){ */ static void unionCloseSources(UnionTab *pTab, int nMax){ while( pTab->pClosable && pTab->nOpen>nMax ){ + UnionSrc *p; UnionSrc **pp; for(pp=&pTab->pClosable; (*pp)->pNextClosable; pp=&(*pp)->pNextClosable); - assert( (*pp)->db ); - sqlite3_close((*pp)->db); - (*pp)->db = 0; + p = *pp; + assert( p->db ); + sqlite3_close(p->db); + p->db = 0; *pp = 0; pTab->nOpen--; + unionInvokeOpenClose(pTab, p, 1, 0); } } @@ -377,13 +484,19 @@ static int unionDisconnect(sqlite3_vtab *pVtab){ int i; for(i=0; inSrc; i++){ UnionSrc *pSrc = &pTab->aSrc[i]; + int bHaveSrcDb = (pSrc->db!=0); + sqlite3_close(pSrc->db); + if( bHaveSrcDb ){ + unionInvokeOpenClose(pTab, pSrc, 1, 0); + } sqlite3_free(pSrc->zDb); sqlite3_free(pSrc->zTab); sqlite3_free(pSrc->zFile); - sqlite3_close(pSrc->db); + sqlite3_free(pSrc->zContext); } + sqlite3_finalize(pTab->pNotFound); + sqlite3_finalize(pTab->pOpenClose); sqlite3_free(pTab->zSourceStr); - sqlite3_free(pTab->zNotFoundCallback); sqlite3_free(pTab->aSrc); sqlite3_free(pTab); } @@ -496,29 +609,31 @@ static int unionSourceCheck(UnionTab *pTab, char **pzErr){ return rc; } - /* ** Try to open the swarmvtab database. If initially unable, invoke the ** not-found callback UDF and then try again. */ static int unionOpenDatabaseInner(UnionTab *pTab, UnionSrc *pSrc, char **pzErr){ - int rc = SQLITE_OK; - static const int openFlags = - SQLITE_OPEN_READONLY | SQLITE_OPEN_URI; + static const int openFlags = SQLITE_OPEN_READONLY | SQLITE_OPEN_URI; + int rc; + + rc = unionInvokeOpenClose(pTab, pSrc, 0, pzErr); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0); if( rc==SQLITE_OK ) return rc; - if( pTab->zNotFoundCallback ){ - char *zSql = sqlite3_mprintf("SELECT \"%w\"(%Q);", - pTab->zNotFoundCallback, pSrc->zFile); + if( pTab->pNotFound ){ sqlite3_close(pSrc->db); pSrc->db = 0; - if( zSql==0 ){ - *pzErr = sqlite3_mprintf("out of memory"); - return SQLITE_NOMEM; + sqlite3_bind_text(pTab->pNotFound, 1, pSrc->zFile, -1, SQLITE_STATIC); + if( pTab->bHasContext ){ + sqlite3_bind_text(pTab->pNotFound, 2, pSrc->zContext, -1, SQLITE_STATIC); + } + sqlite3_step(pTab->pNotFound); + if( SQLITE_OK!=(rc = sqlite3_reset(pTab->pNotFound)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); + return rc; } - rc = sqlite3_exec(pTab->db, zSql, 0, 0, pzErr); - sqlite3_free(zSql); - if( rc ) return rc; rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0); } if( rc!=SQLITE_OK ){ @@ -572,6 +687,7 @@ static int unionOpenDatabase(UnionTab *pTab, int iSrc, char **pzErr){ }else{ sqlite3_close(pSrc->db); pSrc->db = 0; + unionInvokeOpenClose(pTab, pSrc, 1, 0); } } @@ -627,6 +743,132 @@ static int unionFinalizeCsrStmt(UnionCsr *pCsr){ return rc; } +/* +** Return true if the argument is a space, tab, CR or LF character. +*/ +static int union_isspace(char c){ + return (c==' ' || c=='\n' || c=='\r' || c=='\t'); +} + +/* +** Return true if the argument is an alphanumeric character in the +** ASCII range. +*/ +static int union_isidchar(char c){ + return ((c>='a' && c<='z') || (c>='A' && c<'Z') || (c>='0' && c<='9')); +} + +/* +** This function is called to handle all arguments following the first +** (the SQL statement) passed to a swarmvtab (not unionvtab) CREATE +** VIRTUAL TABLE statement. It may bind parameters to the SQL statement +** or configure members of the UnionTab object passed as the second +** argument. +** +** Refer to header comments at the top of this file for a description +** of the arguments parsed. +** +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, if an error occurs, *pRc is set to an SQLite error +** code. In this case *pzErr may be set to point to a buffer containing +** an English language error message. It is the responsibility of the +** caller to eventually free the buffer using sqlite3_free(). +*/ +static void unionConfigureVtab( + int *pRc, /* IN/OUT: Error code */ + UnionTab *pTab, /* Table to configure */ + sqlite3_stmt *pStmt, /* SQL statement to find sources */ + int nArg, /* Number of entries in azArg[] array */ + const char * const *azArg, /* Array of arguments to consider */ + char **pzErr /* OUT: Error message */ +){ + int rc = *pRc; + int i; + if( rc==SQLITE_OK ){ + pTab->bHasContext = (sqlite3_column_count(pStmt)>4); + } + for(i=0; rc==SQLITE_OK && inMaxOpen = atoi(zVal); + if( pTab->nMaxOpen<=0 ){ + *pzErr = sqlite3_mprintf("swarmvtab: illegal maxopen value"); + rc = SQLITE_ERROR; + } + }else if( nOpt==7 && 0==sqlite3_strnicmp(zOpt, "missing", 7) ){ + if( pTab->pNotFound ){ + *pzErr = sqlite3_mprintf( + "swarmvtab: duplicate \"missing\" option"); + rc = SQLITE_ERROR; + }else{ + pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db, + "SELECT \"%w\"(?%s)", zVal, pTab->bHasContext ? ",?" : "" + ); + } + }else if( nOpt==9 && 0==sqlite3_strnicmp(zOpt, "openclose", 9) ){ + if( pTab->pOpenClose ){ + *pzErr = sqlite3_mprintf( + "swarmvtab: duplicate \"openclose\" option"); + rc = SQLITE_ERROR; + }else{ + pTab->pOpenClose = unionPreparePrintf(&rc, pzErr, pTab->db, + "SELECT \"%w\"(?,?%s)", zVal, pTab->bHasContext ? ",?" : "" + ); + } + }else{ + *pzErr = sqlite3_mprintf("swarmvtab: unrecognized option: %s",zOpt); + rc = SQLITE_ERROR; + } + sqlite3_free(zVal); + } + }else{ + if( i==0 && nArg==1 ){ + pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db, + "SELECT \"%w\"(?)", zArg + ); + }else{ + *pzErr = sqlite3_mprintf( "swarmvtab: parse error: %s", azArg[i]); + rc = SQLITE_ERROR; + } + } + sqlite3_free(zArg); + } + } + *pRc = rc; +} + /* ** xConnect/xCreate method. ** @@ -654,7 +896,7 @@ static int unionConnect( /* unionvtab tables may only be created in the temp schema */ *pzErr = sqlite3_mprintf("%s tables must be created in TEMP schema", zVtab); rc = SQLITE_ERROR; - }else if( argc!=4 && argc!=5 ){ + }else if( argc<4 || (argc>4 && bSwarm==0) ){ *pzErr = sqlite3_mprintf("wrong number of arguments for %s", zVtab); rc = SQLITE_ERROR; }else{ @@ -673,6 +915,17 @@ static int unionConnect( /* Allocate the UnionTab structure */ pTab = unionMalloc(&rc, sizeof(UnionTab)); + if( pTab ){ + assert( rc==SQLITE_OK ); + pTab->db = db; + pTab->bSwarm = bSwarm; + pTab->nMaxOpen = SWARMVTAB_MAX_OPEN; + } + + /* Parse other CVT arguments, if any */ + if( bSwarm ){ + unionConfigureVtab(&rc, pTab, pStmt, argc-4, &argv[4], pzErr); + } /* Iterate through the rows returned by the SQL statement specified ** as an argument to the CREATE VIRTUAL TABLE statement. */ @@ -715,17 +968,15 @@ static int unionConnect( }else{ pSrc->zDb = unionStrdup(&rc, zDb); } + if( pTab->bHasContext ){ + const char *zContext = (const char*)sqlite3_column_text(pStmt, 4); + pSrc->zContext = unionStrdup(&rc, zContext); + } } } unionFinalize(&rc, pStmt, pzErr); pStmt = 0; - /* Capture the not-found callback UDF name */ - if( rc==SQLITE_OK && argc>=5 ){ - pTab->zNotFoundCallback = unionStrdup(&rc, argv[4]); - unionDequote(pTab->zNotFoundCallback); - } - /* It is an error if the SELECT statement returned zero rows. If only ** because there is no way to determine the schema of the virtual ** table in this case. */ @@ -738,9 +989,6 @@ static int unionConnect( ** compatible schemas. For swarmvtab, attach the first database and ** check that the first table is a rowid table only. */ if( rc==SQLITE_OK ){ - pTab->db = db; - pTab->bSwarm = bSwarm; - pTab->nMaxOpen = SWARMVTAB_MAX_OPEN; if( bSwarm ){ rc = unionOpenDatabase(pTab, 0, pzErr); }else{ diff --git a/ext/misc/vtablog.c b/ext/misc/vtablog.c new file mode 100644 index 0000000000..9e03fd455d --- /dev/null +++ b/ext/misc/vtablog.c @@ -0,0 +1,509 @@ +/* +** 2017-08-10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements a virtual table that prints diagnostic information +** on stdout when its key interfaces are called. This is intended for +** interactive analysis and debugging of virtual table interfaces. +** +** Usage example: +** +** .load ./vtablog +** CREATE VIRTUAL TABLE temp.log USING vtablog( +** schema='CREATE TABLE x(a,b,c)', +** rows=25 +** ); +** SELECT * FROM log; +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include +#include +#include +#include + + +/* vtablog_vtab is a subclass of sqlite3_vtab which will +** serve as the underlying representation of a vtablog virtual table +*/ +typedef struct vtablog_vtab vtablog_vtab; +struct vtablog_vtab { + sqlite3_vtab base; /* Base class - must be first */ + int nRow; /* Number of rows in the table */ + int iInst; /* Instance number for this vtablog table */ + int nCursor; /* Number of cursors created */ +}; + +/* vtablog_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct vtablog_cursor vtablog_cursor; +struct vtablog_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + int iCursor; /* Cursor number */ + sqlite3_int64 iRowid; /* The rowid */ +}; + +/* Skip leading whitespace. Return a pointer to the first non-whitespace +** character, or to the zero terminator if the string has only whitespace */ +static const char *vtablog_skip_whitespace(const char *z){ + while( isspace((unsigned char)z[0]) ) z++; + return z; +} + +/* Remove trailing whitespace from the end of string z[] */ +static void vtablog_trim_whitespace(char *z){ + size_t n = strlen(z); + while( n>0 && isspace((unsigned char)z[n]) ) n--; + z[n] = 0; +} + +/* Dequote the string */ +static void vtablog_dequote(char *z){ + int j; + char cQuote = z[0]; + size_t i, n; + + if( cQuote!='\'' && cQuote!='"' ) return; + n = strlen(z); + if( n<2 || z[n-1]!=z[0] ) return; + for(i=1, j=0; inRow = 10; + if( zNRow ) pNew->nRow = atoi(zNRow); + pNew->iInst = iInst; + } + return rc; +} +static int vtablogCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return vtablogConnectCreate(db,pAux,argc,argv,ppVtab,pzErr,1); +} +static int vtablogConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return vtablogConnectCreate(db,pAux,argc,argv,ppVtab,pzErr,0); +} + + +/* +** This method is the destructor for vtablog_cursor objects. +*/ +static int vtablogDisconnect(sqlite3_vtab *pVtab){ + vtablog_vtab *pTab = (vtablog_vtab*)pVtab; + printf("vtablogDisconnect(%d)\n", pTab->iInst); + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** This method is the destructor for vtablog_cursor objects. +*/ +static int vtablogDestroy(sqlite3_vtab *pVtab){ + vtablog_vtab *pTab = (vtablog_vtab*)pVtab; + printf("vtablogDestroy(%d)\n", pTab->iInst); + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new vtablog_cursor object. +*/ +static int vtablogOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + vtablog_vtab *pTab = (vtablog_vtab*)p; + vtablog_cursor *pCur; + printf("vtablogOpen(tab=%d, cursor=%d)\n", pTab->iInst, ++pTab->nCursor); + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + pCur->iCursor = pTab->nCursor; + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Destructor for a vtablog_cursor. +*/ +static int vtablogClose(sqlite3_vtab_cursor *cur){ + vtablog_cursor *pCur = (vtablog_cursor*)cur; + vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; + printf("vtablogClose(tab=%d, cursor=%d)\n", pTab->iInst, pCur->iCursor); + sqlite3_free(cur); + return SQLITE_OK; +} + + +/* +** Advance a vtablog_cursor to its next row of output. +*/ +static int vtablogNext(sqlite3_vtab_cursor *cur){ + vtablog_cursor *pCur = (vtablog_cursor*)cur; + vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; + printf("vtablogNext(tab=%d, cursor=%d) rowid %d -> %d\n", + pTab->iInst, pCur->iCursor, (int)pCur->iRowid, (int)pCur->iRowid+1); + pCur->iRowid++; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the vtablog_cursor +** is currently pointing. +*/ +static int vtablogColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + vtablog_cursor *pCur = (vtablog_cursor*)cur; + vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; + char zVal[50]; + + if( i<26 ){ + sqlite3_snprintf(sizeof(zVal),zVal,"%c%d", + "abcdefghijklmnopqrstuvwyz"[i], pCur->iRowid); + }else{ + sqlite3_snprintf(sizeof(zVal),zVal,"{%d}%d", i, pCur->iRowid); + } + printf("vtablogColumn(tab=%d, cursor=%d, i=%d): [%s]\n", + pTab->iInst, pCur->iCursor, i, zVal); + sqlite3_result_text(ctx, zVal, -1, SQLITE_TRANSIENT); + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int vtablogRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + vtablog_cursor *pCur = (vtablog_cursor*)cur; + vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; + printf("vtablogRowid(tab=%d, cursor=%d): %d\n", + pTab->iInst, pCur->iCursor, (int)pCur->iRowid); + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int vtablogEof(sqlite3_vtab_cursor *cur){ + vtablog_cursor *pCur = (vtablog_cursor*)cur; + vtablog_vtab *pTab = (vtablog_vtab*)cur->pVtab; + int rc = pCur->iRowid >= pTab->nRow; + printf("vtablogEof(tab=%d, cursor=%d): %d\n", + pTab->iInst, pCur->iCursor, rc); + return rc; +} + +/* +** Output an sqlite3_value object's value as an SQL literal. +*/ +static void vtablogQuote(sqlite3_value *p){ + char z[50]; + switch( sqlite3_value_type(p) ){ + case SQLITE_NULL: { + printf("NULL"); + break; + } + case SQLITE_INTEGER: { + sqlite3_snprintf(50,z,"%lld", sqlite3_value_int64(p)); + printf("%s", z); + break; + } + case SQLITE_FLOAT: { + sqlite3_snprintf(50,z,"%!.20g", sqlite3_value_double(p)); + printf("%s", z); + break; + } + case SQLITE_BLOB: { + int n = sqlite3_value_bytes(p); + const unsigned char *z = (const unsigned char*)sqlite3_value_blob(p); + int i; + printf("x'"); + for(i=0; ipVtab; + printf("vtablogFilter(tab=%d, cursor=%d):\n", pTab->iInst, pCur->iCursor); + pCur->iRowid = 0; + return SQLITE_OK; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the vtablog virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +*/ +static int vtablogBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + printf("vtablogBestIndex(tab=%d):\n", pTab->iInst); + pIdxInfo->estimatedCost = (double)500; + pIdxInfo->estimatedRows = 500; + return SQLITE_OK; +} + +/* +** SQLite invokes this method to INSERT, UPDATE, or DELETE content from +** the table. +** +** This implementation does not actually make any changes to the table +** content. It merely logs the fact that the method was invoked +*/ +static int vtablogUpdate( + sqlite3_vtab *tab, + int argc, + sqlite3_value **argv, + sqlite_int64 *pRowid +){ + vtablog_vtab *pTab = (vtablog_vtab*)tab; + int i; + printf("vtablogUpdate(tab=%d):\n", pTab->iInst); + printf(" argc=%d\n", argc); + for(i=0; i +#include +#include + +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +#ifndef SQLITE_AMALGAMATION + +typedef sqlite3_int64 i64; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; +#define MIN(a,b) ((a)<(b) ? (a) : (b)) + +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif + +#endif /* SQLITE_AMALGAMATION */ + +/* +** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK. +** +** In some ways it would be better to obtain these values from system +** header files. But, the dependency is undesirable and (a) these +** have been stable for decades, (b) the values are part of POSIX and +** are also made explicit in [man stat], and (c) are part of the +** file format for zip archives. +*/ +#ifndef S_IFDIR +# define S_IFDIR 0040000 +#endif +#ifndef S_IFREG +# define S_IFREG 0100000 +#endif +#ifndef S_IFLNK +# define S_IFLNK 0120000 +#endif + +static const char ZIPFILE_SCHEMA[] = + "CREATE TABLE y(" + "name PRIMARY KEY," /* 0: Name of file in zip archive */ + "mode," /* 1: POSIX mode for file */ + "mtime," /* 2: Last modification time (secs since 1970)*/ + "sz," /* 3: Size of object */ + "rawdata," /* 4: Raw data */ + "data," /* 5: Uncompressed data */ + "method," /* 6: Compression method (integer) */ + "z HIDDEN" /* 7: Name of zip file */ + ") WITHOUT ROWID;"; + +#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ +#define ZIPFILE_BUFFER_SIZE (64*1024) + + +/* +** Magic numbers used to read and write zip files. +** +** ZIPFILE_NEWENTRY_MADEBY: +** Use this value for the "version-made-by" field in new zip file +** entries. The upper byte indicates "unix", and the lower byte +** indicates that the zip file matches pkzip specification 3.0. +** This is what info-zip seems to do. +** +** ZIPFILE_NEWENTRY_REQUIRED: +** Value for "version-required-to-extract" field of new entries. +** Version 2.0 is required to support folders and deflate compression. +** +** ZIPFILE_NEWENTRY_FLAGS: +** Value for "general-purpose-bit-flags" field of new entries. Bit +** 11 means "utf-8 filename and comment". +** +** ZIPFILE_SIGNATURE_CDS: +** First 4 bytes of a valid CDS record. +** +** ZIPFILE_SIGNATURE_LFH: +** First 4 bytes of a valid LFH record. +** +** ZIPFILE_SIGNATURE_EOCD +** First 4 bytes of a valid EOCD record. +*/ +#define ZIPFILE_EXTRA_TIMESTAMP 0x5455 +#define ZIPFILE_NEWENTRY_MADEBY ((3<<8) + 30) +#define ZIPFILE_NEWENTRY_REQUIRED 20 +#define ZIPFILE_NEWENTRY_FLAGS 0x800 +#define ZIPFILE_SIGNATURE_CDS 0x02014b50 +#define ZIPFILE_SIGNATURE_LFH 0x04034b50 +#define ZIPFILE_SIGNATURE_EOCD 0x06054b50 + +/* +** The sizes of the fixed-size part of each of the three main data +** structures in a zip archive. +*/ +#define ZIPFILE_LFH_FIXED_SZ 30 +#define ZIPFILE_EOCD_FIXED_SZ 22 +#define ZIPFILE_CDS_FIXED_SZ 46 + +/* +*** 4.3.16 End of central directory record: +*** +*** end of central dir signature 4 bytes (0x06054b50) +*** number of this disk 2 bytes +*** number of the disk with the +*** start of the central directory 2 bytes +*** total number of entries in the +*** central directory on this disk 2 bytes +*** total number of entries in +*** the central directory 2 bytes +*** size of the central directory 4 bytes +*** offset of start of central +*** directory with respect to +*** the starting disk number 4 bytes +*** .ZIP file comment length 2 bytes +*** .ZIP file comment (variable size) +*/ +typedef struct ZipfileEOCD ZipfileEOCD; +struct ZipfileEOCD { + u16 iDisk; + u16 iFirstDisk; + u16 nEntry; + u16 nEntryTotal; + u32 nSize; + u32 iOffset; +}; + +/* +*** 4.3.12 Central directory structure: +*** +*** ... +*** +*** central file header signature 4 bytes (0x02014b50) +*** version made by 2 bytes +*** version needed to extract 2 bytes +*** general purpose bit flag 2 bytes +*** compression method 2 bytes +*** last mod file time 2 bytes +*** last mod file date 2 bytes +*** crc-32 4 bytes +*** compressed size 4 bytes +*** uncompressed size 4 bytes +*** file name length 2 bytes +*** extra field length 2 bytes +*** file comment length 2 bytes +*** disk number start 2 bytes +*** internal file attributes 2 bytes +*** external file attributes 4 bytes +*** relative offset of local header 4 bytes +*/ +typedef struct ZipfileCDS ZipfileCDS; +struct ZipfileCDS { + u16 iVersionMadeBy; + u16 iVersionExtract; + u16 flags; + u16 iCompression; + u16 mTime; + u16 mDate; + u32 crc32; + u32 szCompressed; + u32 szUncompressed; + u16 nFile; + u16 nExtra; + u16 nComment; + u16 iDiskStart; + u16 iInternalAttr; + u32 iExternalAttr; + u32 iOffset; + char *zFile; /* Filename (sqlite3_malloc()) */ +}; + +/* +*** 4.3.7 Local file header: +*** +*** local file header signature 4 bytes (0x04034b50) +*** version needed to extract 2 bytes +*** general purpose bit flag 2 bytes +*** compression method 2 bytes +*** last mod file time 2 bytes +*** last mod file date 2 bytes +*** crc-32 4 bytes +*** compressed size 4 bytes +*** uncompressed size 4 bytes +*** file name length 2 bytes +*** extra field length 2 bytes +*** +*/ +typedef struct ZipfileLFH ZipfileLFH; +struct ZipfileLFH { + u16 iVersionExtract; + u16 flags; + u16 iCompression; + u16 mTime; + u16 mDate; + u32 crc32; + u32 szCompressed; + u32 szUncompressed; + u16 nFile; + u16 nExtra; +}; + +typedef struct ZipfileEntry ZipfileEntry; +struct ZipfileEntry { + ZipfileCDS cds; /* Parsed CDS record */ + u32 mUnixTime; /* Modification time, in UNIX format */ + u8 *aExtra; /* cds.nExtra+cds.nComment bytes of extra data */ + i64 iDataOff; /* Offset to data in file (if aData==0) */ + u8 *aData; /* cds.szCompressed bytes of compressed data */ + ZipfileEntry *pNext; /* Next element in in-memory CDS */ +}; + +/* +** Cursor type for zipfile tables. +*/ +typedef struct ZipfileCsr ZipfileCsr; +struct ZipfileCsr { + sqlite3_vtab_cursor base; /* Base class - must be first */ + i64 iId; /* Cursor ID */ + u8 bEof; /* True when at EOF */ + u8 bNoop; /* If next xNext() call is no-op */ + + /* Used outside of write transactions */ + FILE *pFile; /* Zip file */ + i64 iNextOff; /* Offset of next record in central directory */ + ZipfileEOCD eocd; /* Parse of central directory record */ + + ZipfileEntry *pFreeEntry; /* Free this list when cursor is closed or reset */ + ZipfileEntry *pCurrent; /* Current entry */ + ZipfileCsr *pCsrNext; /* Next cursor on same virtual table */ +}; + +typedef struct ZipfileTab ZipfileTab; +struct ZipfileTab { + sqlite3_vtab base; /* Base class - must be first */ + char *zFile; /* Zip file this table accesses (may be NULL) */ + sqlite3 *db; /* Host database connection */ + u8 *aBuffer; /* Temporary buffer used for various tasks */ + + ZipfileCsr *pCsrList; /* List of cursors */ + i64 iNextCsrid; + + /* The following are used by write transactions only */ + ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */ + ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */ + FILE *pWriteFd; /* File handle open on zip archive */ + i64 szCurrent; /* Current size of zip archive */ + i64 szOrig; /* Size of archive at start of transaction */ +}; + +/* +** Set the error message contained in context ctx to the results of +** vprintf(zFmt, ...). +*/ +static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ + char *zMsg = 0; + va_list ap; + va_start(ap, zFmt); + zMsg = sqlite3_vmprintf(zFmt, ap); + sqlite3_result_error(ctx, zMsg, -1); + sqlite3_free(zMsg); + va_end(ap); +} + +/* +** If string zIn is quoted, dequote it in place. Otherwise, if the string +** is not quoted, do nothing. +*/ +static void zipfileDequote(char *zIn){ + char q = zIn[0]; + if( q=='"' || q=='\'' || q=='`' || q=='[' ){ + int iIn = 1; + int iOut = 0; + if( q=='[' ) q = ']'; + while( ALWAYS(zIn[iIn]) ){ + char c = zIn[iIn++]; + if( c==q && zIn[iIn++]!=q ) break; + zIn[iOut++] = c; + } + zIn[iOut] = '\0'; + } +} + +/* +** Construct a new ZipfileTab virtual table object. +** +** argv[0] -> module name ("zipfile") +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> "column name" and other module argument fields. +*/ +static int zipfileConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE; + int nFile = 0; + const char *zFile = 0; + ZipfileTab *pNew = 0; + int rc; + + /* If the table name is not "zipfile", require that the argument be + ** specified. This stops zipfile tables from being created as: + ** + ** CREATE VIRTUAL TABLE zzz USING zipfile(); + ** + ** It does not prevent: + ** + ** CREATE VIRTUAL TABLE zipfile USING zipfile(); + */ + assert( 0==sqlite3_stricmp(argv[0], "zipfile") ); + if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){ + *pzErr = sqlite3_mprintf("zipfile constructor requires one argument"); + return SQLITE_ERROR; + } + + if( argc>3 ){ + zFile = argv[3]; + nFile = (int)strlen(zFile)+1; + } + + rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA); + if( rc==SQLITE_OK ){ + pNew = (ZipfileTab*)sqlite3_malloc(nByte+nFile); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, nByte+nFile); + pNew->db = db; + pNew->aBuffer = (u8*)&pNew[1]; + if( zFile ){ + pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE]; + memcpy(pNew->zFile, zFile, nFile); + zipfileDequote(pNew->zFile); + } + } + *ppVtab = (sqlite3_vtab*)pNew; + return rc; +} + +/* +** Free the ZipfileEntry structure indicated by the only argument. +*/ +static void zipfileEntryFree(ZipfileEntry *p){ + if( p ){ + sqlite3_free(p->cds.zFile); + sqlite3_free(p); + } +} + +/* +** Release resources that should be freed at the end of a write +** transaction. +*/ +static void zipfileCleanupTransaction(ZipfileTab *pTab){ + ZipfileEntry *pEntry; + ZipfileEntry *pNext; + + if( pTab->pWriteFd ){ + fclose(pTab->pWriteFd); + pTab->pWriteFd = 0; + } + for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){ + pNext = pEntry->pNext; + zipfileEntryFree(pEntry); + } + pTab->pFirstEntry = 0; + pTab->pLastEntry = 0; + pTab->szCurrent = 0; + pTab->szOrig = 0; +} + +/* +** This method is the destructor for zipfile vtab objects. +*/ +static int zipfileDisconnect(sqlite3_vtab *pVtab){ + zipfileCleanupTransaction((ZipfileTab*)pVtab); + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new ZipfileCsr object. +*/ +static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){ + ZipfileTab *pTab = (ZipfileTab*)p; + ZipfileCsr *pCsr; + pCsr = sqlite3_malloc(sizeof(*pCsr)); + *ppCsr = (sqlite3_vtab_cursor*)pCsr; + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(*pCsr)); + pCsr->iId = ++pTab->iNextCsrid; + pCsr->pCsrNext = pTab->pCsrList; + pTab->pCsrList = pCsr; + return SQLITE_OK; +} + +/* +** Reset a cursor back to the state it was in when first returned +** by zipfileOpen(). +*/ +static void zipfileResetCursor(ZipfileCsr *pCsr){ + ZipfileEntry *p; + ZipfileEntry *pNext; + + pCsr->bEof = 0; + if( pCsr->pFile ){ + fclose(pCsr->pFile); + pCsr->pFile = 0; + zipfileEntryFree(pCsr->pCurrent); + pCsr->pCurrent = 0; + } + + for(p=pCsr->pFreeEntry; p; p=pNext){ + pNext = p->pNext; + zipfileEntryFree(p); + } +} + +/* +** Destructor for an ZipfileCsr. +*/ +static int zipfileClose(sqlite3_vtab_cursor *cur){ + ZipfileCsr *pCsr = (ZipfileCsr*)cur; + ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab); + ZipfileCsr **pp; + zipfileResetCursor(pCsr); + + /* Remove this cursor from the ZipfileTab.pCsrList list. */ + for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext)); + *pp = pCsr->pCsrNext; + + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Set the error message for the virtual table associated with cursor +** pCsr to the results of vprintf(zFmt, ...). +*/ +static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){ + va_list ap; + va_start(ap, zFmt); + sqlite3_free(pTab->base.zErrMsg); + pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap); + va_end(ap); +} +static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){ + va_list ap; + va_start(ap, zFmt); + sqlite3_free(pCsr->base.pVtab->zErrMsg); + pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); + va_end(ap); +} + +/* +** Read nRead bytes of data from offset iOff of file pFile into buffer +** aRead[]. Return SQLITE_OK if successful, or an SQLite error code +** otherwise. +** +** If an error does occur, output variable (*pzErrmsg) may be set to point +** to an English language error message. It is the responsibility of the +** caller to eventually free this buffer using +** sqlite3_free(). +*/ +static int zipfileReadData( + FILE *pFile, /* Read from this file */ + u8 *aRead, /* Read into this buffer */ + int nRead, /* Number of bytes to read */ + i64 iOff, /* Offset to read from */ + char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */ +){ + size_t n; + fseek(pFile, (long)iOff, SEEK_SET); + n = fread(aRead, 1, nRead, pFile); + if( (int)n!=nRead ){ + *pzErrmsg = sqlite3_mprintf("error in fread()"); + return SQLITE_ERROR; + } + return SQLITE_OK; +} + +static int zipfileAppendData( + ZipfileTab *pTab, + const u8 *aWrite, + int nWrite +){ + size_t n; + fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET); + n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd); + if( (int)n!=nWrite ){ + pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()"); + return SQLITE_ERROR; + } + pTab->szCurrent += nWrite; + return SQLITE_OK; +} + +/* +** Read and return a 16-bit little-endian unsigned integer from buffer aBuf. +*/ +static u16 zipfileGetU16(const u8 *aBuf){ + return (aBuf[1] << 8) + aBuf[0]; +} + +/* +** Read and return a 32-bit little-endian unsigned integer from buffer aBuf. +*/ +static u32 zipfileGetU32(const u8 *aBuf){ + return ((u32)(aBuf[3]) << 24) + + ((u32)(aBuf[2]) << 16) + + ((u32)(aBuf[1]) << 8) + + ((u32)(aBuf[0]) << 0); +} + +/* +** Write a 16-bit little endiate integer into buffer aBuf. +*/ +static void zipfilePutU16(u8 *aBuf, u16 val){ + aBuf[0] = val & 0xFF; + aBuf[1] = (val>>8) & 0xFF; +} + +/* +** Write a 32-bit little endiate integer into buffer aBuf. +*/ +static void zipfilePutU32(u8 *aBuf, u32 val){ + aBuf[0] = val & 0xFF; + aBuf[1] = (val>>8) & 0xFF; + aBuf[2] = (val>>16) & 0xFF; + aBuf[3] = (val>>24) & 0xFF; +} + +#define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) ) +#define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) ) + +#define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; } +#define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; } + +/* +** Magic numbers used to read CDS records. +*/ +#define ZIPFILE_CDS_NFILE_OFF 28 +#define ZIPFILE_CDS_SZCOMPRESSED_OFF 20 + +/* +** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR +** if the record is not well-formed, or SQLITE_OK otherwise. +*/ +static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){ + u8 *aRead = aBuf; + u32 sig = zipfileRead32(aRead); + int rc = SQLITE_OK; + if( sig!=ZIPFILE_SIGNATURE_CDS ){ + rc = SQLITE_ERROR; + }else{ + pCDS->iVersionMadeBy = zipfileRead16(aRead); + pCDS->iVersionExtract = zipfileRead16(aRead); + pCDS->flags = zipfileRead16(aRead); + pCDS->iCompression = zipfileRead16(aRead); + pCDS->mTime = zipfileRead16(aRead); + pCDS->mDate = zipfileRead16(aRead); + pCDS->crc32 = zipfileRead32(aRead); + pCDS->szCompressed = zipfileRead32(aRead); + pCDS->szUncompressed = zipfileRead32(aRead); + assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); + pCDS->nFile = zipfileRead16(aRead); + pCDS->nExtra = zipfileRead16(aRead); + pCDS->nComment = zipfileRead16(aRead); + pCDS->iDiskStart = zipfileRead16(aRead); + pCDS->iInternalAttr = zipfileRead16(aRead); + pCDS->iExternalAttr = zipfileRead32(aRead); + pCDS->iOffset = zipfileRead32(aRead); + assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] ); + } + + return rc; +} + +/* +** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR +** if the record is not well-formed, or SQLITE_OK otherwise. +*/ +static int zipfileReadLFH( + u8 *aBuffer, + ZipfileLFH *pLFH +){ + u8 *aRead = aBuffer; + int rc = SQLITE_OK; + + u32 sig = zipfileRead32(aRead); + if( sig!=ZIPFILE_SIGNATURE_LFH ){ + rc = SQLITE_ERROR; + }else{ + pLFH->iVersionExtract = zipfileRead16(aRead); + pLFH->flags = zipfileRead16(aRead); + pLFH->iCompression = zipfileRead16(aRead); + pLFH->mTime = zipfileRead16(aRead); + pLFH->mDate = zipfileRead16(aRead); + pLFH->crc32 = zipfileRead32(aRead); + pLFH->szCompressed = zipfileRead32(aRead); + pLFH->szUncompressed = zipfileRead32(aRead); + pLFH->nFile = zipfileRead16(aRead); + pLFH->nExtra = zipfileRead16(aRead); + } + return rc; +} + + +/* +** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields. +** Scan through this buffer to find an "extra-timestamp" field. If one +** exists, extract the 32-bit modification-timestamp from it and store +** the value in output parameter *pmTime. +** +** Zero is returned if no extra-timestamp record could be found (and so +** *pmTime is left unchanged), or non-zero otherwise. +** +** The general format of an extra field is: +** +** Header ID 2 bytes +** Data Size 2 bytes +** Data N bytes +*/ +static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){ + int ret = 0; + u8 *p = aExtra; + u8 *pEnd = &aExtra[nExtra]; + + while( p modtime is present */ + *pmTime = zipfileGetU32(&p[1]); + ret = 1; + } + break; + } + } + + p += nByte; + } + return ret; +} + +/* +** Convert the standard MS-DOS timestamp stored in the mTime and mDate +** fields of the CDS structure passed as the only argument to a 32-bit +** UNIX seconds-since-the-epoch timestamp. Return the result. +** +** "Standard" MS-DOS time format: +** +** File modification time: +** Bits 00-04: seconds divided by 2 +** Bits 05-10: minute +** Bits 11-15: hour +** File modification date: +** Bits 00-04: day +** Bits 05-08: month (1-12) +** Bits 09-15: years from 1980 +** +** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx +*/ +static u32 zipfileMtime(ZipfileCDS *pCDS){ + int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); + int M = ((pCDS->mDate >> 5) & 0x0F); + int D = (pCDS->mDate & 0x1F); + int B = -13; + + int sec = (pCDS->mTime & 0x1F)*2; + int min = (pCDS->mTime >> 5) & 0x3F; + int hr = (pCDS->mTime >> 11) & 0x1F; + i64 JD; + + /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */ + + /* Calculate the JD in seconds for noon on the day in question */ + if( M<3 ){ + Y = Y-1; + M = M+12; + } + JD = (i64)(24*60*60) * ( + (int)(365.25 * (Y + 4716)) + + (int)(30.6001 * (M + 1)) + + D + B - 1524 + ); + + /* Correct the JD for the time within the day */ + JD += (hr-12) * 3600 + min * 60 + sec; + + /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */ + return (u32)(JD - (i64)(24405875) * 24*60*6); +} + +/* +** The opposite of zipfileMtime(). This function populates the mTime and +** mDate fields of the CDS structure passed as the first argument according +** to the UNIX timestamp value passed as the second. +*/ +static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){ + /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */ + i64 JD = (i64)2440588 + mUnixTime / (24*60*60); + + int A, B, C, D, E; + int yr, mon, day; + int hr, min, sec; + + A = (int)((JD - 1867216.25)/36524.25); + A = (int)(JD + 1 + A - (A/4)); + B = A + 1524; + C = (int)((B - 122.1)/365.25); + D = (36525*(C&32767))/100; + E = (int)((B-D)/30.6001); + + day = B - D - (int)(30.6001*E); + mon = (E<14 ? E-1 : E-13); + yr = mon>2 ? C-4716 : C-4715; + + hr = (mUnixTime % (24*60*60)) / (60*60); + min = (mUnixTime % (60*60)) / 60; + sec = (mUnixTime % 60); + + if( yr>=1980 ){ + pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9)); + pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11)); + }else{ + pCds->mDate = pCds->mTime = 0; + } + + assert( mUnixTime<315507600 + || mUnixTime==zipfileMtime(pCds) + || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) + /* || (mUnixTime % 2) */ + ); +} + +/* +** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in +** size) containing an entire zip archive image. Or, if aBlob is NULL, +** then pFile is a file-handle open on a zip file. In either case, this +** function creates a ZipfileEntry object based on the zip archive entry +** for which the CDS record is at offset iOff. +** +** If successful, SQLITE_OK is returned and (*ppEntry) set to point to +** the new object. Otherwise, an SQLite error code is returned and the +** final value of (*ppEntry) undefined. +*/ +static int zipfileGetEntry( + ZipfileTab *pTab, /* Store any error message here */ + const u8 *aBlob, /* Pointer to in-memory file image */ + int nBlob, /* Size of aBlob[] in bytes */ + FILE *pFile, /* If aBlob==0, read from this file */ + i64 iOff, /* Offset of CDS record */ + ZipfileEntry **ppEntry /* OUT: Pointer to new object */ +){ + u8 *aRead; + char **pzErr = &pTab->base.zErrMsg; + int rc = SQLITE_OK; + + if( aBlob==0 ){ + aRead = pTab->aBuffer; + rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); + }else{ + aRead = (u8*)&aBlob[iOff]; + } + + if( rc==SQLITE_OK ){ + int nAlloc; + ZipfileEntry *pNew; + + int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]); + int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]); + nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]); + + nAlloc = sizeof(ZipfileEntry) + nExtra; + if( aBlob ){ + nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]); + } + + pNew = (ZipfileEntry*)sqlite3_malloc(nAlloc); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pNew, 0, sizeof(ZipfileEntry)); + rc = zipfileReadCDS(aRead, &pNew->cds); + if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff); + }else if( aBlob==0 ){ + rc = zipfileReadData( + pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr + ); + }else{ + aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; + } + } + + if( rc==SQLITE_OK ){ + u32 *pt = &pNew->mUnixTime; + pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead); + pNew->aExtra = (u8*)&pNew[1]; + memcpy(pNew->aExtra, &aRead[nFile], nExtra); + if( pNew->cds.zFile==0 ){ + rc = SQLITE_NOMEM; + }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){ + pNew->mUnixTime = zipfileMtime(&pNew->cds); + } + } + + if( rc==SQLITE_OK ){ + static const int szFix = ZIPFILE_LFH_FIXED_SZ; + ZipfileLFH lfh; + if( pFile ){ + rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); + }else{ + aRead = (u8*)&aBlob[pNew->cds.iOffset]; + } + + rc = zipfileReadLFH(aRead, &lfh); + if( rc==SQLITE_OK ){ + pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; + pNew->iDataOff += lfh.nFile + lfh.nExtra; + if( aBlob && pNew->cds.szCompressed ){ + pNew->aData = &pNew->aExtra[nExtra]; + memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); + } + }else{ + *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", + (int)pNew->cds.iOffset + ); + } + } + + if( rc!=SQLITE_OK ){ + zipfileEntryFree(pNew); + }else{ + *ppEntry = pNew; + } + } + + return rc; +} + +/* +** Advance an ZipfileCsr to its next row of output. +*/ +static int zipfileNext(sqlite3_vtab_cursor *cur){ + ZipfileCsr *pCsr = (ZipfileCsr*)cur; + int rc = SQLITE_OK; + + if( pCsr->pFile ){ + i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize; + zipfileEntryFree(pCsr->pCurrent); + pCsr->pCurrent = 0; + if( pCsr->iNextOff>=iEof ){ + pCsr->bEof = 1; + }else{ + ZipfileEntry *p = 0; + ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab); + rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p); + if( rc==SQLITE_OK ){ + pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ; + pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment; + } + pCsr->pCurrent = p; + } + }else{ + if( !pCsr->bNoop ){ + pCsr->pCurrent = pCsr->pCurrent->pNext; + } + if( pCsr->pCurrent==0 ){ + pCsr->bEof = 1; + } + } + + pCsr->bNoop = 0; + return rc; +} + +static void zipfileFree(void *p) { + sqlite3_free(p); +} + +/* +** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the +** size is nOut bytes. This function uncompresses the data and sets the +** return value in context pCtx to the result (a blob). +** +** If an error occurs, an error code is left in pCtx instead. +*/ +static void zipfileInflate( + sqlite3_context *pCtx, /* Store result here */ + const u8 *aIn, /* Compressed data */ + int nIn, /* Size of buffer aIn[] in bytes */ + int nOut /* Expected output size */ +){ + u8 *aRes = sqlite3_malloc(nOut); + if( aRes==0 ){ + sqlite3_result_error_nomem(pCtx); + }else{ + int err; + z_stream str; + memset(&str, 0, sizeof(str)); + + str.next_in = (Byte*)aIn; + str.avail_in = nIn; + str.next_out = (Byte*)aRes; + str.avail_out = nOut; + + err = inflateInit2(&str, -15); + if( err!=Z_OK ){ + zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err); + }else{ + err = inflate(&str, Z_NO_FLUSH); + if( err!=Z_STREAM_END ){ + zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err); + }else{ + sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree); + aRes = 0; + } + } + sqlite3_free(aRes); + inflateEnd(&str); + } +} + +/* +** Buffer aIn (size nIn bytes) contains uncompressed data. This function +** compresses it and sets (*ppOut) to point to a buffer containing the +** compressed data. The caller is responsible for eventually calling +** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) +** is set to the size of buffer (*ppOut) in bytes. +** +** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error +** code is returned and an error message left in virtual-table handle +** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this +** case. +*/ +static int zipfileDeflate( + const u8 *aIn, int nIn, /* Input */ + u8 **ppOut, int *pnOut, /* Output */ + char **pzErr /* OUT: Error message */ +){ + int nAlloc = (int)compressBound(nIn); + u8 *aOut; + int rc = SQLITE_OK; + + aOut = (u8*)sqlite3_malloc(nAlloc); + if( aOut==0 ){ + rc = SQLITE_NOMEM; + }else{ + int res; + z_stream str; + memset(&str, 0, sizeof(str)); + str.next_in = (Bytef*)aIn; + str.avail_in = nIn; + str.next_out = aOut; + str.avail_out = nAlloc; + + deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + res = deflate(&str, Z_FINISH); + + if( res==Z_STREAM_END ){ + *ppOut = aOut; + *pnOut = (int)str.total_out; + }else{ + sqlite3_free(aOut); + *pzErr = sqlite3_mprintf("zipfile: deflate() error"); + rc = SQLITE_ERROR; + } + deflateEnd(&str); + } + + return rc; +} + + +/* +** Return values of columns for the row at which the series_cursor +** is currently pointing. +*/ +static int zipfileColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + ZipfileCsr *pCsr = (ZipfileCsr*)cur; + ZipfileCDS *pCDS = &pCsr->pCurrent->cds; + int rc = SQLITE_OK; + switch( i ){ + case 0: /* name */ + sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT); + break; + case 1: /* mode */ + /* TODO: Whether or not the following is correct surely depends on + ** the platform on which the archive was created. */ + sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16); + break; + case 2: { /* mtime */ + sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime); + break; + } + case 3: { /* sz */ + if( sqlite3_vtab_nochange(ctx)==0 ){ + sqlite3_result_int64(ctx, pCDS->szUncompressed); + } + break; + } + case 4: /* rawdata */ + if( sqlite3_vtab_nochange(ctx) ) break; + case 5: { /* data */ + if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){ + int sz = pCDS->szCompressed; + int szFinal = pCDS->szUncompressed; + if( szFinal>0 ){ + u8 *aBuf; + u8 *aFree = 0; + if( pCsr->pCurrent->aData ){ + aBuf = pCsr->pCurrent->aData; + }else{ + aBuf = aFree = sqlite3_malloc(sz); + if( aBuf==0 ){ + rc = SQLITE_NOMEM; + }else{ + FILE *pFile = pCsr->pFile; + if( pFile==0 ){ + pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd; + } + rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff, + &pCsr->base.pVtab->zErrMsg + ); + } + } + if( rc==SQLITE_OK ){ + if( i==5 && pCDS->iCompression ){ + zipfileInflate(ctx, aBuf, sz, szFinal); + }else{ + sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT); + } + } + sqlite3_free(aFree); + }else{ + /* Figure out if this is a directory or a zero-sized file. Consider + ** it to be a directory either if the mode suggests so, or if + ** the final character in the name is '/'. */ + u32 mode = pCDS->iExternalAttr >> 16; + if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){ + sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC); + } + } + } + break; + } + case 6: /* method */ + sqlite3_result_int(ctx, pCDS->iCompression); + break; + default: /* z */ + assert( i==7 ); + sqlite3_result_int64(ctx, pCsr->iId); + break; + } + + return rc; +} + +/* +** Return TRUE if the cursor is at EOF. +*/ +static int zipfileEof(sqlite3_vtab_cursor *cur){ + ZipfileCsr *pCsr = (ZipfileCsr*)cur; + return pCsr->bEof; +} + +/* +** If aBlob is not NULL, then it points to a buffer nBlob bytes in size +** containing an entire zip archive image. Or, if aBlob is NULL, then pFile +** is guaranteed to be a file-handle open on a zip file. +** +** This function attempts to locate the EOCD record within the zip archive +** and populate *pEOCD with the results of decoding it. SQLITE_OK is +** returned if successful. Otherwise, an SQLite error code is returned and +** an English language error message may be left in virtual-table pTab. +*/ +static int zipfileReadEOCD( + ZipfileTab *pTab, /* Return errors here */ + const u8 *aBlob, /* Pointer to in-memory file image */ + int nBlob, /* Size of aBlob[] in bytes */ + FILE *pFile, /* Read from this file if aBlob==0 */ + ZipfileEOCD *pEOCD /* Object to populate */ +){ + u8 *aRead = pTab->aBuffer; /* Temporary buffer */ + int nRead; /* Bytes to read from file */ + int rc = SQLITE_OK; + + if( aBlob==0 ){ + i64 iOff; /* Offset to read from */ + i64 szFile; /* Total size of file in bytes */ + fseek(pFile, 0, SEEK_END); + szFile = (i64)ftell(pFile); + if( szFile==0 ){ + memset(pEOCD, 0, sizeof(ZipfileEOCD)); + return SQLITE_OK; + } + nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE)); + iOff = szFile - nRead; + rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg); + }else{ + nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE)); + aRead = (u8*)&aBlob[nBlob-nRead]; + } + + if( rc==SQLITE_OK ){ + int i; + + /* Scan backwards looking for the signature bytes */ + for(i=nRead-20; i>=0; i--){ + if( aRead[i]==0x50 && aRead[i+1]==0x4b + && aRead[i+2]==0x05 && aRead[i+3]==0x06 + ){ + break; + } + } + if( i<0 ){ + pTab->base.zErrMsg = sqlite3_mprintf( + "cannot find end of central directory record" + ); + return SQLITE_ERROR; + } + + aRead += i+4; + pEOCD->iDisk = zipfileRead16(aRead); + pEOCD->iFirstDisk = zipfileRead16(aRead); + pEOCD->nEntry = zipfileRead16(aRead); + pEOCD->nEntryTotal = zipfileRead16(aRead); + pEOCD->nSize = zipfileRead32(aRead); + pEOCD->iOffset = zipfileRead32(aRead); + } + + return rc; +} + +/* +** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry +** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added +** to the end of the list. Otherwise, it is added to the list immediately +** before pBefore (which is guaranteed to be a part of said list). +*/ +static void zipfileAddEntry( + ZipfileTab *pTab, + ZipfileEntry *pBefore, + ZipfileEntry *pNew +){ + assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) ); + assert( pNew->pNext==0 ); + if( pBefore==0 ){ + if( pTab->pFirstEntry==0 ){ + pTab->pFirstEntry = pTab->pLastEntry = pNew; + }else{ + assert( pTab->pLastEntry->pNext==0 ); + pTab->pLastEntry->pNext = pNew; + pTab->pLastEntry = pNew; + } + }else{ + ZipfileEntry **pp; + for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext)); + pNew->pNext = pBefore; + *pp = pNew; + } +} + +static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){ + ZipfileEOCD eocd; + int rc; + int i; + i64 iOff; + + rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd); + iOff = eocd.iOffset; + for(i=0; rc==SQLITE_OK && ipWriteFd, iOff, &pNew); + + if( rc==SQLITE_OK ){ + zipfileAddEntry(pTab, 0, pNew); + iOff += ZIPFILE_CDS_FIXED_SZ; + iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment; + } + } + return rc; +} + +/* +** xFilter callback. +*/ +static int zipfileFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + ZipfileTab *pTab = (ZipfileTab*)cur->pVtab; + ZipfileCsr *pCsr = (ZipfileCsr*)cur; + const char *zFile = 0; /* Zip file to scan */ + int rc = SQLITE_OK; /* Return Code */ + int bInMemory = 0; /* True for an in-memory zipfile */ + + zipfileResetCursor(pCsr); + + if( pTab->zFile ){ + zFile = pTab->zFile; + }else if( idxNum==0 ){ + zipfileCursorErr(pCsr, "zipfile() function requires an argument"); + return SQLITE_ERROR; + }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ + const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]); + int nBlob = sqlite3_value_bytes(argv[0]); + assert( pTab->pFirstEntry==0 ); + rc = zipfileLoadDirectory(pTab, aBlob, nBlob); + pCsr->pFreeEntry = pTab->pFirstEntry; + pTab->pFirstEntry = pTab->pLastEntry = 0; + if( rc!=SQLITE_OK ) return rc; + bInMemory = 1; + }else{ + zFile = (const char*)sqlite3_value_text(argv[0]); + } + + if( 0==pTab->pWriteFd && 0==bInMemory ){ + pCsr->pFile = fopen(zFile, "rb"); + if( pCsr->pFile==0 ){ + zipfileCursorErr(pCsr, "cannot open file: %s", zFile); + rc = SQLITE_ERROR; + }else{ + rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd); + if( rc==SQLITE_OK ){ + if( pCsr->eocd.nEntry==0 ){ + pCsr->bEof = 1; + }else{ + pCsr->iNextOff = pCsr->eocd.iOffset; + rc = zipfileNext(cur); + } + } + } + }else{ + pCsr->bNoop = 1; + pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry; + rc = zipfileNext(cur); + } + + return rc; +} + +/* +** xBestIndex callback. +*/ +static int zipfileBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; + + for(i=0; inConstraint; i++){ + const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; + if( pCons->usable==0 ) continue; + if( pCons->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue; + break; + } + + if( inConstraint ){ + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->estimatedCost = 1000.0; + pIdxInfo->idxNum = 1; + }else{ + pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50); + pIdxInfo->idxNum = 0; + } + + return SQLITE_OK; +} + +static ZipfileEntry *zipfileNewEntry(const char *zPath){ + ZipfileEntry *pNew; + pNew = sqlite3_malloc(sizeof(ZipfileEntry)); + if( pNew ){ + memset(pNew, 0, sizeof(ZipfileEntry)); + pNew->cds.zFile = sqlite3_mprintf("%s", zPath); + if( pNew->cds.zFile==0 ){ + sqlite3_free(pNew); + pNew = 0; + } + } + return pNew; +} + +static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){ + ZipfileCDS *pCds = &pEntry->cds; + u8 *a = aBuf; + + pCds->nExtra = 9; + + /* Write the LFH itself */ + zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH); + zipfileWrite16(a, pCds->iVersionExtract); + zipfileWrite16(a, pCds->flags); + zipfileWrite16(a, pCds->iCompression); + zipfileWrite16(a, pCds->mTime); + zipfileWrite16(a, pCds->mDate); + zipfileWrite32(a, pCds->crc32); + zipfileWrite32(a, pCds->szCompressed); + zipfileWrite32(a, pCds->szUncompressed); + zipfileWrite16(a, (u16)pCds->nFile); + zipfileWrite16(a, pCds->nExtra); + assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] ); + + /* Add the file name */ + memcpy(a, pCds->zFile, (int)pCds->nFile); + a += (int)pCds->nFile; + + /* The "extra" data */ + zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); + zipfileWrite16(a, 5); + *a++ = 0x01; + zipfileWrite32(a, pEntry->mUnixTime); + + return a-aBuf; +} + +static int zipfileAppendEntry( + ZipfileTab *pTab, + ZipfileEntry *pEntry, + const u8 *pData, + int nData +){ + u8 *aBuf = pTab->aBuffer; + int nBuf; + int rc; + + nBuf = zipfileSerializeLFH(pEntry, aBuf); + rc = zipfileAppendData(pTab, aBuf, nBuf); + if( rc==SQLITE_OK ){ + pEntry->iDataOff = pTab->szCurrent; + rc = zipfileAppendData(pTab, pData, nData); + } + + return rc; +} + +static int zipfileGetMode( + sqlite3_value *pVal, + int bIsDir, /* If true, default to directory */ + u32 *pMode, /* OUT: Mode value */ + char **pzErr /* OUT: Error message */ +){ + const char *z = (const char*)sqlite3_value_text(pVal); + u32 mode = 0; + if( z==0 ){ + mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)); + }else if( z[0]>='0' && z[0]<='9' ){ + mode = (unsigned int)sqlite3_value_int(pVal); + }else{ + const char zTemplate[11] = "-rwxrwxrwx"; + int i; + if( strlen(z)!=10 ) goto parse_error; + switch( z[0] ){ + case '-': mode |= S_IFREG; break; + case 'd': mode |= S_IFDIR; break; + case 'l': mode |= S_IFLNK; break; + default: goto parse_error; + } + for(i=1; i<10; i++){ + if( z[i]==zTemplate[i] ) mode |= 1 << (9-i); + else if( z[i]!='-' ) goto parse_error; + } + } + if( ((mode & S_IFDIR)==0)==bIsDir ){ + /* The "mode" attribute is a directory, but data has been specified. + ** Or vice-versa - no data but "mode" is a file or symlink. */ + *pzErr = sqlite3_mprintf("zipfile: mode does not match data"); + return SQLITE_CONSTRAINT; + } + *pMode = mode; + return SQLITE_OK; + + parse_error: + *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z); + return SQLITE_ERROR; +} + +/* +** Both (const char*) arguments point to nul-terminated strings. Argument +** nB is the value of strlen(zB). This function returns 0 if the strings are +** identical, ignoring any trailing '/' character in either path. */ +static int zipfileComparePath(const char *zA, const char *zB, int nB){ + int nA = (int)strlen(zA); + if( zA[nA-1]=='/' ) nA--; + if( zB[nB-1]=='/' ) nB--; + if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0; + return 1; +} + +static int zipfileBegin(sqlite3_vtab *pVtab){ + ZipfileTab *pTab = (ZipfileTab*)pVtab; + int rc = SQLITE_OK; + + assert( pTab->pWriteFd==0 ); + + /* Open a write fd on the file. Also load the entire central directory + ** structure into memory. During the transaction any new file data is + ** appended to the archive file, but the central directory is accumulated + ** in main-memory until the transaction is committed. */ + pTab->pWriteFd = fopen(pTab->zFile, "ab+"); + if( pTab->pWriteFd==0 ){ + pTab->base.zErrMsg = sqlite3_mprintf( + "zipfile: failed to open file %s for writing", pTab->zFile + ); + rc = SQLITE_ERROR; + }else{ + fseek(pTab->pWriteFd, 0, SEEK_END); + pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd); + rc = zipfileLoadDirectory(pTab, 0, 0); + } + + if( rc!=SQLITE_OK ){ + zipfileCleanupTransaction(pTab); + } + + return rc; +} + +/* +** Return the current time as a 32-bit timestamp in UNIX epoch format (like +** time(2)). +*/ +static u32 zipfileTime(void){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); + u32 ret; + if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ + i64 ms; + pVfs->xCurrentTimeInt64(pVfs, &ms); + ret = (u32)((ms/1000) - ((i64)24405875 * 8640)); + }else{ + double day; + pVfs->xCurrentTime(pVfs, &day); + ret = (u32)((day - 2440587.5) * 86400); + } + return ret; +} + +/* +** Return a 32-bit timestamp in UNIX epoch format. +** +** If the value passed as the only argument is either NULL or an SQL NULL, +** return the current time. Otherwise, return the value stored in (*pVal) +** cast to a 32-bit unsigned integer. +*/ +static u32 zipfileGetTime(sqlite3_value *pVal){ + if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ + return zipfileTime(); + } + return (u32)sqlite3_value_int64(pVal); +} + +/* +** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry +** linked list. Remove it from the list and free the object. +*/ +static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){ + if( pOld ){ + ZipfileEntry **pp; + for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext)); + *pp = (*pp)->pNext; + zipfileEntryFree(pOld); + } +} + +/* +** xUpdate method. +*/ +static int zipfileUpdate( + sqlite3_vtab *pVtab, + int nVal, + sqlite3_value **apVal, + sqlite_int64 *pRowid +){ + ZipfileTab *pTab = (ZipfileTab*)pVtab; + int rc = SQLITE_OK; /* Return Code */ + ZipfileEntry *pNew = 0; /* New in-memory CDS entry */ + + u32 mode = 0; /* Mode for new entry */ + u32 mTime = 0; /* Modification time for new entry */ + i64 sz = 0; /* Uncompressed size */ + const char *zPath = 0; /* Path for new entry */ + int nPath = 0; /* strlen(zPath) */ + const u8 *pData = 0; /* Pointer to buffer containing content */ + int nData = 0; /* Size of pData buffer in bytes */ + int iMethod = 0; /* Compression method for new entry */ + u8 *pFree = 0; /* Free this */ + char *zFree = 0; /* Also free this */ + ZipfileEntry *pOld = 0; + ZipfileEntry *pOld2 = 0; + int bUpdate = 0; /* True for an update that modifies "name" */ + int bIsDir = 0; + u32 iCrc32 = 0; + + if( pTab->pWriteFd==0 ){ + rc = zipfileBegin(pVtab); + if( rc!=SQLITE_OK ) return rc; + } + + /* If this is a DELETE or UPDATE, find the archive entry to delete. */ + if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ + const char *zDelete = (const char*)sqlite3_value_text(apVal[0]); + int nDelete = (int)strlen(zDelete); + if( nVal>1 ){ + const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]); + if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){ + bUpdate = 1; + } + } + for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){ + if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){ + break; + } + assert( pOld->pNext ); + } + } + + if( nVal>1 ){ + /* Check that "sz" and "rawdata" are both NULL: */ + if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){ + zipfileTableErr(pTab, "sz must be NULL"); + rc = SQLITE_CONSTRAINT; + } + if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){ + zipfileTableErr(pTab, "rawdata must be NULL"); + rc = SQLITE_CONSTRAINT; + } + + if( rc==SQLITE_OK ){ + if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){ + /* data=NULL. A directory */ + bIsDir = 1; + }else{ + /* Value specified for "data", and possibly "method". This must be + ** a regular file or a symlink. */ + const u8 *aIn = sqlite3_value_blob(apVal[7]); + int nIn = sqlite3_value_bytes(apVal[7]); + int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL; + + iMethod = sqlite3_value_int(apVal[8]); + sz = nIn; + pData = aIn; + nData = nIn; + if( iMethod!=0 && iMethod!=8 ){ + zipfileTableErr(pTab, "unknown compression method: %d", iMethod); + rc = SQLITE_CONSTRAINT; + }else{ + if( bAuto || iMethod ){ + int nCmp; + rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg); + if( rc==SQLITE_OK ){ + if( iMethod || nCmpbase.zErrMsg); + } + + if( rc==SQLITE_OK ){ + zPath = (const char*)sqlite3_value_text(apVal[2]); + nPath = (int)strlen(zPath); + mTime = zipfileGetTime(apVal[4]); + } + + if( rc==SQLITE_OK && bIsDir ){ + /* For a directory, check that the last character in the path is a + ** '/'. This appears to be required for compatibility with info-zip + ** (the unzip command on unix). It does not create directories + ** otherwise. */ + if( zPath[nPath-1]!='/' ){ + zFree = sqlite3_mprintf("%s/", zPath); + if( zFree==0 ){ rc = SQLITE_NOMEM; } + zPath = (const char*)zFree; + nPath++; + } + } + + /* Check that we're not inserting a duplicate entry -OR- updating an + ** entry with a path, thereby making it into a duplicate. */ + if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){ + ZipfileEntry *p; + for(p=pTab->pFirstEntry; p; p=p->pNext){ + if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){ + switch( sqlite3_vtab_on_conflict(pTab->db) ){ + case SQLITE_IGNORE: { + goto zipfile_update_done; + } + case SQLITE_REPLACE: { + pOld2 = p; + break; + } + default: { + zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath); + rc = SQLITE_CONSTRAINT; + break; + } + } + break; + } + } + } + + if( rc==SQLITE_OK ){ + /* Create the new CDS record. */ + pNew = zipfileNewEntry(zPath); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; + pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; + pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS; + pNew->cds.iCompression = (u16)iMethod; + zipfileMtimeToDos(&pNew->cds, mTime); + pNew->cds.crc32 = iCrc32; + pNew->cds.szCompressed = nData; + pNew->cds.szUncompressed = (u32)sz; + pNew->cds.iExternalAttr = (mode<<16); + pNew->cds.iOffset = (u32)pTab->szCurrent; + pNew->cds.nFile = (u16)nPath; + pNew->mUnixTime = (u32)mTime; + rc = zipfileAppendEntry(pTab, pNew, pData, nData); + zipfileAddEntry(pTab, pOld, pNew); + } + } + } + + if( rc==SQLITE_OK && (pOld || pOld2) ){ + ZipfileCsr *pCsr; + for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ + if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){ + pCsr->pCurrent = pCsr->pCurrent->pNext; + pCsr->bNoop = 1; + } + } + + zipfileRemoveEntryFromList(pTab, pOld); + zipfileRemoveEntryFromList(pTab, pOld2); + } + +zipfile_update_done: + sqlite3_free(pFree); + sqlite3_free(zFree); + return rc; +} + +static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){ + u8 *a = aBuf; + zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD); + zipfileWrite16(a, p->iDisk); + zipfileWrite16(a, p->iFirstDisk); + zipfileWrite16(a, p->nEntry); + zipfileWrite16(a, p->nEntryTotal); + zipfileWrite32(a, p->nSize); + zipfileWrite32(a, p->iOffset); + zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/ + + return a-aBuf; +} + +static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){ + int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer); + assert( nBuf==ZIPFILE_EOCD_FIXED_SZ ); + return zipfileAppendData(pTab, pTab->aBuffer, nBuf); +} + +/* +** Serialize the CDS structure into buffer aBuf[]. Return the number +** of bytes written. +*/ +static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){ + u8 *a = aBuf; + ZipfileCDS *pCDS = &pEntry->cds; + + if( pEntry->aExtra==0 ){ + pCDS->nExtra = 9; + } + + zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS); + zipfileWrite16(a, pCDS->iVersionMadeBy); + zipfileWrite16(a, pCDS->iVersionExtract); + zipfileWrite16(a, pCDS->flags); + zipfileWrite16(a, pCDS->iCompression); + zipfileWrite16(a, pCDS->mTime); + zipfileWrite16(a, pCDS->mDate); + zipfileWrite32(a, pCDS->crc32); + zipfileWrite32(a, pCDS->szCompressed); + zipfileWrite32(a, pCDS->szUncompressed); + assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); + zipfileWrite16(a, pCDS->nFile); + zipfileWrite16(a, pCDS->nExtra); + zipfileWrite16(a, pCDS->nComment); + zipfileWrite16(a, pCDS->iDiskStart); + zipfileWrite16(a, pCDS->iInternalAttr); + zipfileWrite32(a, pCDS->iExternalAttr); + zipfileWrite32(a, pCDS->iOffset); + + memcpy(a, pCDS->zFile, pCDS->nFile); + a += pCDS->nFile; + + if( pEntry->aExtra ){ + int n = (int)pCDS->nExtra + (int)pCDS->nComment; + memcpy(a, pEntry->aExtra, n); + a += n; + }else{ + assert( pCDS->nExtra==9 ); + zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); + zipfileWrite16(a, 5); + *a++ = 0x01; + zipfileWrite32(a, pEntry->mUnixTime); + } + + return a-aBuf; +} + +static int zipfileCommit(sqlite3_vtab *pVtab){ + ZipfileTab *pTab = (ZipfileTab*)pVtab; + int rc = SQLITE_OK; + if( pTab->pWriteFd ){ + i64 iOffset = pTab->szCurrent; + ZipfileEntry *p; + ZipfileEOCD eocd; + int nEntry = 0; + + /* Write out all entries */ + for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){ + int n = zipfileSerializeCDS(p, pTab->aBuffer); + rc = zipfileAppendData(pTab, pTab->aBuffer, n); + nEntry++; + } + + /* Write out the EOCD record */ + eocd.iDisk = 0; + eocd.iFirstDisk = 0; + eocd.nEntry = (u16)nEntry; + eocd.nEntryTotal = (u16)nEntry; + eocd.nSize = (u32)(pTab->szCurrent - iOffset); + eocd.iOffset = (u32)iOffset; + rc = zipfileAppendEOCD(pTab, &eocd); + + zipfileCleanupTransaction(pTab); + } + return rc; +} + +static int zipfileRollback(sqlite3_vtab *pVtab){ + return zipfileCommit(pVtab); +} + +static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){ + ZipfileCsr *pCsr; + for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ + if( iId==pCsr->iId ) break; + } + return pCsr; +} + +static void zipfileFunctionCds( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + ZipfileCsr *pCsr; + ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context); + assert( argc>0 ); + + pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0])); + if( pCsr ){ + ZipfileCDS *p = &pCsr->pCurrent->cds; + char *zRes = sqlite3_mprintf("{" + "\"version-made-by\" : %u, " + "\"version-to-extract\" : %u, " + "\"flags\" : %u, " + "\"compression\" : %u, " + "\"time\" : %u, " + "\"date\" : %u, " + "\"crc32\" : %u, " + "\"compressed-size\" : %u, " + "\"uncompressed-size\" : %u, " + "\"file-name-length\" : %u, " + "\"extra-field-length\" : %u, " + "\"file-comment-length\" : %u, " + "\"disk-number-start\" : %u, " + "\"internal-attr\" : %u, " + "\"external-attr\" : %u, " + "\"offset\" : %u }", + (u32)p->iVersionMadeBy, (u32)p->iVersionExtract, + (u32)p->flags, (u32)p->iCompression, + (u32)p->mTime, (u32)p->mDate, + (u32)p->crc32, (u32)p->szCompressed, + (u32)p->szUncompressed, (u32)p->nFile, + (u32)p->nExtra, (u32)p->nComment, + (u32)p->iDiskStart, (u32)p->iInternalAttr, + (u32)p->iExternalAttr, (u32)p->iOffset + ); + + if( zRes==0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); + sqlite3_free(zRes); + } + } +} + +/* +** xFindFunction method. +*/ +static int zipfileFindFunction( + sqlite3_vtab *pVtab, /* Virtual table handle */ + int nArg, /* Number of SQL function arguments */ + const char *zName, /* Name of SQL function */ + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ + void **ppArg /* OUT: User data for *pxFunc */ +){ + if( sqlite3_stricmp("zipfile_cds", zName)==0 ){ + *pxFunc = zipfileFunctionCds; + *ppArg = (void*)pVtab; + return 1; + } + return 0; +} + +typedef struct ZipfileBuffer ZipfileBuffer; +struct ZipfileBuffer { + u8 *a; /* Pointer to buffer */ + int n; /* Size of buffer in bytes */ + int nAlloc; /* Byte allocated at a[] */ +}; + +typedef struct ZipfileCtx ZipfileCtx; +struct ZipfileCtx { + int nEntry; + ZipfileBuffer body; + ZipfileBuffer cds; +}; + +static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){ + if( pBuf->n+nByte>pBuf->nAlloc ){ + u8 *aNew; + int nNew = pBuf->n ? pBuf->n*2 : 512; + int nReq = pBuf->n + nByte; + + while( nNewa, nNew); + if( aNew==0 ) return SQLITE_NOMEM; + pBuf->a = aNew; + pBuf->nAlloc = nNew; + } + return SQLITE_OK; +} + +/* +** xStep() callback for the zipfile() aggregate. This can be called in +** any of the following ways: +** +** SELECT zipfile(name,data) ... +** SELECT zipfile(name,mode,mtime,data) ... +** SELECT zipfile(name,mode,mtime,data,method) ... +*/ +void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ + ZipfileCtx *p; /* Aggregate function context */ + ZipfileEntry e; /* New entry to add to zip archive */ + + sqlite3_value *pName = 0; + sqlite3_value *pMode = 0; + sqlite3_value *pMtime = 0; + sqlite3_value *pData = 0; + sqlite3_value *pMethod = 0; + + int bIsDir = 0; + u32 mode; + int rc = SQLITE_OK; + char *zErr = 0; + + int iMethod = -1; /* Compression method to use (0 or 8) */ + + const u8 *aData = 0; /* Possibly compressed data for new entry */ + int nData = 0; /* Size of aData[] in bytes */ + int szUncompressed = 0; /* Size of data before compression */ + u8 *aFree = 0; /* Free this before returning */ + u32 iCrc32 = 0; /* crc32 of uncompressed data */ + + char *zName = 0; /* Path (name) of new entry */ + int nName = 0; /* Size of zName in bytes */ + char *zFree = 0; /* Free this before returning */ + int nByte; + + memset(&e, 0, sizeof(e)); + p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); + if( p==0 ) return; + + /* Martial the arguments into stack variables */ + if( nVal!=2 && nVal!=4 && nVal!=5 ){ + zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()"); + rc = SQLITE_ERROR; + goto zipfile_step_out; + } + pName = apVal[0]; + if( nVal==2 ){ + pData = apVal[1]; + }else{ + pMode = apVal[1]; + pMtime = apVal[2]; + pData = apVal[3]; + if( nVal==5 ){ + pMethod = apVal[4]; + } + } + + /* Check that the 'name' parameter looks ok. */ + zName = (char*)sqlite3_value_text(pName); + nName = sqlite3_value_bytes(pName); + if( zName==0 ){ + zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL"); + rc = SQLITE_ERROR; + goto zipfile_step_out; + } + + /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use + ** deflate compression) or NULL (choose automatically). */ + if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){ + iMethod = (int)sqlite3_value_int64(pMethod); + if( iMethod!=0 && iMethod!=8 ){ + zErr = sqlite3_mprintf("illegal method value: %d", iMethod); + rc = SQLITE_ERROR; + goto zipfile_step_out; + } + } + + /* Now inspect the data. If this is NULL, then the new entry must be a + ** directory. Otherwise, figure out whether or not the data should + ** be deflated or simply stored in the zip archive. */ + if( sqlite3_value_type(pData)==SQLITE_NULL ){ + bIsDir = 1; + iMethod = 0; + }else{ + aData = sqlite3_value_blob(pData); + szUncompressed = nData = sqlite3_value_bytes(pData); + iCrc32 = crc32(0, aData, nData); + if( iMethod<0 || iMethod==8 ){ + int nOut = 0; + rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr); + if( rc!=SQLITE_OK ){ + goto zipfile_step_out; + } + if( iMethod==8 || nOut1 && zName[nName-2]=='/' ) nName--; + } + } + + /* Assemble the ZipfileEntry object for the new zip archive entry */ + e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; + e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; + e.cds.flags = ZIPFILE_NEWENTRY_FLAGS; + e.cds.iCompression = (u16)iMethod; + zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime); + e.cds.crc32 = iCrc32; + e.cds.szCompressed = nData; + e.cds.szUncompressed = szUncompressed; + e.cds.iExternalAttr = (mode<<16); + e.cds.iOffset = p->body.n; + e.cds.nFile = (u16)nName; + e.cds.zFile = zName; + + /* Append the LFH to the body of the new archive */ + nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9; + if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out; + p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]); + + /* Append the data to the body of the new archive */ + if( nData>0 ){ + if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out; + memcpy(&p->body.a[p->body.n], aData, nData); + p->body.n += nData; + } + + /* Append the CDS record to the directory of the new archive */ + nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9; + if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out; + p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]); + + /* Increment the count of entries in the archive */ + p->nEntry++; + + zipfile_step_out: + sqlite3_free(aFree); + sqlite3_free(zFree); + if( rc ){ + if( zErr ){ + sqlite3_result_error(pCtx, zErr, -1); + }else{ + sqlite3_result_error_code(pCtx, rc); + } + } + sqlite3_free(zErr); +} + +/* +** xFinalize() callback for zipfile aggregate function. +*/ +void zipfileFinal(sqlite3_context *pCtx){ + ZipfileCtx *p; + ZipfileEOCD eocd; + int nZip; + u8 *aZip; + + p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); + if( p==0 ) return; + if( p->nEntry>0 ){ + memset(&eocd, 0, sizeof(eocd)); + eocd.nEntry = (u16)p->nEntry; + eocd.nEntryTotal = (u16)p->nEntry; + eocd.nSize = p->cds.n; + eocd.iOffset = p->body.n; + + nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ; + aZip = (u8*)sqlite3_malloc(nZip); + if( aZip==0 ){ + sqlite3_result_error_nomem(pCtx); + }else{ + memcpy(aZip, p->body.a, p->body.n); + memcpy(&aZip[p->body.n], p->cds.a, p->cds.n); + zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]); + sqlite3_result_blob(pCtx, aZip, nZip, zipfileFree); + } + } + + sqlite3_free(p->body.a); + sqlite3_free(p->cds.a); +} + + +/* +** Register the "zipfile" virtual table. +*/ +static int zipfileRegister(sqlite3 *db){ + static sqlite3_module zipfileModule = { + 1, /* iVersion */ + zipfileConnect, /* xCreate */ + zipfileConnect, /* xConnect */ + zipfileBestIndex, /* xBestIndex */ + zipfileDisconnect, /* xDisconnect */ + zipfileDisconnect, /* xDestroy */ + zipfileOpen, /* xOpen - open a cursor */ + zipfileClose, /* xClose - close a cursor */ + zipfileFilter, /* xFilter - configure scan constraints */ + zipfileNext, /* xNext - advance a cursor */ + zipfileEof, /* xEof - check for end of scan */ + zipfileColumn, /* xColumn - read data */ + 0, /* xRowid - read data */ + zipfileUpdate, /* xUpdate */ + zipfileBegin, /* xBegin */ + 0, /* xSync */ + zipfileCommit, /* xCommit */ + zipfileRollback, /* xRollback */ + zipfileFindFunction, /* xFindMethod */ + 0, /* xRename */ + }; + + int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); + if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, + zipfileStep, zipfileFinal + ); + } + return rc; +} +#else /* SQLITE_OMIT_VIRTUALTABLE */ +# define zipfileRegister(x) SQLITE_OK +#endif + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_zipfile_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + return zipfileRegister(db); +} diff --git a/ext/misc/zorder.c b/ext/misc/zorder.c new file mode 100644 index 0000000000..c385d3c3c3 --- /dev/null +++ b/ext/misc/zorder.c @@ -0,0 +1,102 @@ +/* +** 2018-02-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** SQL functions for z-order (Morton code) transformations. +** +** zorder(X0,X0,..,xN) Generate an N+1 dimension Morton code +** +** unzorder(Z,N,I) Extract the I-th dimension from N-dimensional +** Morton code Z. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +/* +** Functions: zorder(X0,X1,....) +** +** Convert integers X0, X1, ... into morton code. +** +** The output is a signed 64-bit integer. If any argument is too large, +** an error is thrown. +*/ +static void zorderFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_int64 z, x[63]; + int i, j; + z = 0; + for(i=0; i0 ){ + for(i=0; i<63; i++){ + j = i%argc; + z |= (x[j]&1)<>= 1; + } + } + sqlite3_result_int64(context, z); + for(i=0; i>j)&1)<1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){ bVacuum = 1; + }else if( nArg>1 && nArg<=7 + && 0==memcmp(zArg, "-presql", nArg) && i1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i1 && nArg<=9 + && 0==memcmp(zArg, "-statstep", nArg) && i0 && (i % nStatStep)==0 ){ + sqlite3_int64 nUsed; + sqlite3_int64 nHighwater; + sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &nUsed, &nHighwater, 0); + fprintf(stdout, "memory used=%lld highwater=%lld", nUsed, nHighwater); + if( bVacuum==0 ){ + int one; + int two; + sqlite3rbu_bp_progress(pRbu, &one, &two); + fprintf(stdout, " progress=%d/%d\n", one, two); + }else{ + fprintf(stdout, "\n"); + } + fflush(stdout); + } + } + nProgress = sqlite3rbu_progress(pRbu); + rc = sqlite3rbu_close(pRbu, &zErrmsg); + } /* Let the user know what happened. */ switch( rc ){ diff --git a/ext/rbu/rbu1.test b/ext/rbu/rbu1.test index cd41728886..1d16c1cd0a 100644 --- a/ext/rbu/rbu1.test +++ b/ext/rbu/rbu1.test @@ -139,6 +139,7 @@ foreach {tn3 create_vfs destroy_vfs} { foreach {tn2 cmd} { 1 run_rbu 2 step_rbu 3 step_rbu_uri 4 step_rbu_state + 5 step_rbu_legacy } { foreach {tn schema} { 1 { diff --git a/ext/rbu/rbu_common.tcl b/ext/rbu/rbu_common.tcl index a58c3aa0a7..2b263b7660 100644 --- a/ext/rbu/rbu_common.tcl +++ b/ext/rbu/rbu_common.tcl @@ -70,7 +70,24 @@ proc step_rbu {target rbu} { set rc } +proc step_rbu_legacy {target rbu} { + while 1 { + sqlite3rbu rbu $target $rbu + set state [rbu state] + check_prestep_state $target $state + set rc [rbu step] + check_poststep_state $rc $target $state + rbu close + if {$rc != "SQLITE_OK"} break + sqlite3 tmpdb $rbu + tmpdb eval { DELETE FROM rbu_state WHERE k==10 } + tmpdb close + } + set rc +} + proc do_rbu_vacuum_test {tn step} { + forcedelete state.db uplevel [list do_test $tn.1 { if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db } while 1 { diff --git a/ext/rbu/rbucollate.test b/ext/rbu/rbucollate.test new file mode 100644 index 0000000000..3b3b022a5b --- /dev/null +++ b/ext/rbu/rbucollate.test @@ -0,0 +1,63 @@ +# 2018 March 22 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbucollate + +ifcapable !icu_collations { + finish_test + return +} + +db close +sqlite3_shutdown +sqlite3_config_uri 1 +reset_db + +# Create a simple RBU database. That expects to write to a table: +# +# CREATE TABLE t1(a PRIMARY KEY, b, c); +# +proc create_rbu1 {filename} { + forcedelete $filename + sqlite3 rbu1 $filename + rbu1 eval { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES('a', 'one', 1, 0); + INSERT INTO data_t1 VALUES('b', 'two', 2, 0); + INSERT INTO data_t1 VALUES('c', 'three', 3, 0); + } + rbu1 close + return $filename +} + +do_execsql_test 1.0 { + SELECT icu_load_collation('en_US', 'my-collate'); + CREATE TABLE t1(a COLLATE "my-collate" PRIMARY KEY, b, c); +} {{}} + +do_test 1.2 { + create_rbu1 testrbu.db + sqlite3rbu rbu test.db testrbu.db + rbu dbMain_eval { SELECT icu_load_collation('en_US', 'my-collate') } + rbu dbRbu_eval { SELECT icu_load_collation('en_US', 'my-collate') } + while 1 { + set rc [rbu step] + if {$rc!="SQLITE_OK"} break + } + rbu close + db eval { SELECT * FROM t1 } +} {a one 1 b two 2 c three 3} + +#forcedelete testrbu.db +finish_test + diff --git a/ext/rbu/rbumulti.test b/ext/rbu/rbumulti.test new file mode 100644 index 0000000000..59c6538c6c --- /dev/null +++ b/ext/rbu/rbumulti.test @@ -0,0 +1,175 @@ +# 2018 January 11 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests of multiple RBU operations running +# concurrently within the same process. +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbumulti + +db close +sqlite3_shutdown +sqlite3_config_uri 1 + +autoinstall_test_functions + +proc build_db {db} { + $db eval { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + CREATE INDEX i2 ON t1(c); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500 ) + INSERT INTO t1 + SELECT randomblob(10), randomblob(100), randomblob(100) FROM s; + } +} + +proc build_rbu {db} { + $db eval { + CREATE TABLE data_t1(a, b, c, rbu_control); + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 ) + INSERT INTO data_t1 + SELECT randomblob(10), randomblob(100), randomblob(100), 0 FROM s; + } +} + +proc step_rbu2 {bOpenClose openr1 openr2} { + + forcedelete teststate.db1 + forcedelete teststate.db2 + + if {$bOpenClose!=0 && $bOpenClose!=1} { error $bOpenClose } + if {$bOpenClose==0} { + eval $openr1 + eval $openr2 + } + + set b1 0 + set b2 0 + + while {$b1==0 || $b2==0} { + if {$bOpenClose==1} { + if {$b1==0} { eval $openr1 teststate.db1 } + if {$b2==0} { eval $openr2 teststate.db2 } + } + if {$b1==0} { + set rc1 [r1 step] + if {$rc1 != "SQLITE_OK"} { set b1 1 } + } + if {$b2==0} { + set rc2 [r2 step] + if {$rc2 != "SQLITE_OK"} { set b2 1 } + } + if {$bOpenClose==1} { + if {$b1==0} { r1 close } + if {$b2==0} { r2 close } + } + } + + set rc1 [r1 close] + set rc2 [r2 close] + + list $rc1 $rc2 +} + + +for {set i 0} {$i<=3} {incr i} { + + if {$i & 0x01} { + sqlite3rbu_create_vfs -default myrbu "" + } + set bOpenClose [expr $i>>1] + + forcedelete test.db + forcedelete test.db2 + forcedelete rbu.db + forcedelete rbu.db2 + + do_test 1.$i.0 { + sqlite3 db test.db + sqlite3 db2 test.db2 + build_db db + build_db db2 + + sqlite3 rbu1 rbu.db + sqlite3 rbu2 rbu.db2 + + build_rbu rbu1 + build_rbu rbu2 + + rbu1 close + rbu2 close + } {} + + set m1 [db eval {SELECT md5sum(a, b, c) FROM t1}] + set m2 [db2 eval {SELECT md5sum(a, b, c) FROM t1}] + + do_test 1.$i.1 { + step_rbu2 $bOpenClose { + sqlite3rbu r1 test.db rbu.db + } { + sqlite3rbu r2 test.db2 rbu.db2 + } + } {SQLITE_DONE SQLITE_DONE} + + do_execsql_test -db db 1.$i.2.1 { PRAGMA integrity_check } ok + do_execsql_test -db db2 1.$i.2.2 { PRAGMA integrity_check } ok + + do_execsql_test -db db 1.$i.3.1 { SELECT md5sum(a, b, c)==$m1 FROM t1 } 0 + do_execsql_test -db db2 1.$i.3.2 { SELECT md5sum(a, b, c)==$m2 FROM t1 } 0 + + catch { db close } + catch { db2 close } + #----------------------------------------------------------------------- + forcedelete test.db2 + forcedelete test.db + forcedelete rbu.db2 + + do_test 1.$i.4 { + sqlite3 db test.db + sqlite3 db2 test.db2 + build_db db + build_db db2 + sqlite3 rbu2 rbu.db2 + build_rbu rbu2 + rbu2 close + } {} + + set m1 [db eval {SELECT md5sum(a, b, c) FROM t1}] + set m2 [db2 eval {SELECT md5sum(a, b, c) FROM t1}] + + do_test 1.$i.5 { + step_rbu2 $bOpenClose { + sqlite3rbu_vacuum r1 test.db + } { + sqlite3rbu r2 test.db2 rbu.db2 + } + } {SQLITE_DONE SQLITE_DONE} + + do_execsql_test -db db 1.$i.6.1 { SELECT md5sum(a, b, c)==$m1 FROM t1 } 1 + do_execsql_test -db db2 1.$i.6.2 { SELECT md5sum(a, b, c)==$m2 FROM t1 } 0 + + do_execsql_test -db db 1.$i.7.1 { PRAGMA integrity_check } ok + do_execsql_test -db db2 1.$i.7.2 { PRAGMA integrity_check } ok + + catch { db close } + catch { db2 close } + if {$i & 0x01} { + sqlite3rbu_destroy_vfs myrbu + } + +} + + +finish_test + diff --git a/ext/rbu/rbusplit.test b/ext/rbu/rbusplit.test new file mode 100644 index 0000000000..678f388dcf --- /dev/null +++ b/ext/rbu/rbusplit.test @@ -0,0 +1,95 @@ +# 2018 April 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. +# +#*********************************************************************** +# +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbusplit + +db close +sqlite3_shutdown +sqlite3_config_uri 1 + +autoinstall_test_functions + +proc build_db {db} { + $db eval { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE TABLE t2(a PRIMARY KEY, b, c); + + CREATE INDEX t1c ON t1(c); + } +} + +proc build_rbu {filename} { + forcedelete $filename + sqlite3 dbRbu $filename + dbRbu eval { + CREATE TABLE data0_t1(a, b, c, rbu_control); + CREATE TABLE data1_t1(a, b, c, rbu_control); + CREATE TABLE data2_t1(a, b, c, rbu_control); + CREATE TABLE data3_t1(a, b, c, rbu_control); + + CREATE TABLE data_t2(a, b, c, rbu_control); + + INSERT INTO data0_t1 VALUES(1, 1, 1, 0); + INSERT INTO data0_t1 VALUES(2, 2, 2, 0); + INSERT INTO data0_t1 VALUES(3, 3, 3, 0); + INSERT INTO data0_t1 VALUES(4, 4, 4, 0); + INSERT INTO data1_t1 VALUES(5, 5, 5, 0); + INSERT INTO data1_t1 VALUES(6, 6, 6, 0); + INSERT INTO data1_t1 VALUES(7, 7, 7, 0); + INSERT INTO data1_t1 VALUES(8, 8, 8, 0); + INSERT INTO data3_t1 VALUES(9, 9, 9, 0); + + INSERT INTO data_t2 VALUES(1, 1, 1, 0); + INSERT INTO data_t2 VALUES(2, 2, 2, 0); + INSERT INTO data_t2 VALUES(3, 3, 3, 0); + INSERT INTO data_t2 VALUES(4, 4, 4, 0); + INSERT INTO data_t2 VALUES(5, 5, 5, 0); + INSERT INTO data_t2 VALUES(6, 6, 6, 0); + INSERT INTO data_t2 VALUES(7, 7, 7, 0); + INSERT INTO data_t2 VALUES(8, 8, 8, 0); + INSERT INTO data_t2 VALUES(9, 9, 9, 0); + } + + dbRbu close +} + +foreach {tn cmd} { + 1 run_rbu + 2 step_rbu +} { + reset_db + build_db db + build_rbu testrbu.db + + do_test 1.$tn.1 { + $cmd test.db testrbu.db + } {SQLITE_DONE} + do_execsql_test 1.$tn.1 { + SELECT * FROM t1; + } { + 1 1 1 2 2 2 3 3 3 4 4 4 + 5 5 5 6 6 6 7 7 7 8 8 8 + 9 9 9 + } + do_execsql_test 1.$tn.2 { + SELECT * FROM t2; + } { + 1 1 1 2 2 2 3 3 3 4 4 4 + 5 5 5 6 6 6 7 7 7 8 8 8 + 9 9 9 + } +} + +finish_test + diff --git a/ext/rbu/rbutemplimit.test b/ext/rbu/rbutemplimit.test new file mode 100644 index 0000000000..274f870b73 --- /dev/null +++ b/ext/rbu/rbutemplimit.test @@ -0,0 +1,129 @@ +# 2014 August 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbutemplimit + +db close +sqlite3_shutdown +sqlite3_config_uri 1 + +proc setup_databases {} { + forcedelete test.db2 + forcedelete test.db + sqlite3 db test.db + execsql { + -- Create target database schema. + -- + CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB(100), c BLOB(100)); + CREATE TABLE t2(a INTEGER PRIMARY KEY, b BLOB(100), c BLOB(100)); + CREATE INDEX i1b ON t1(b); + CREATE INDEX i1c ON t1(c); + CREATE INDEX i2b ON t2(b); + CREATE INDEX i2c ON t2(c); + + -- Create a large RBU database. + -- + ATTACH 'test.db2' AS rbu; + CREATE TABLE rbu.data_t1(a, b, c, rbu_control); + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<10000 + ) + INSERT INTO data_t1 SELECT i, randomblob(100), randomblob(100), 0 FROM s; + CREATE TABLE rbu.data_t2(a, b, c, rbu_control); + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<15000 + ) + INSERT INTO data_t2 SELECT i, randomblob(100), randomblob(100), 0 FROM s; + } + db close +} + +proc run_rbu_cachesize {target rbu cachesize temp_limit} { + sqlite3rbu rbu $target $rbu + rbu temp_size_limit $temp_limit + sqlite3_exec_nr [rbu db 1] "PRAGMA cache_size = $cachesize" + while 1 { + set rc [rbu step] + set ::A([rbu temp_size]) 1 + if {$rc!="SQLITE_OK"} break + } + list [catch {rbu close} msg] $msg +} + +proc step_rbu_cachesize {target rbu stepsize cachesize temp_limit} { + set res "" + while 1 { + sqlite3rbu rbu $target $rbu + rbu temp_size_limit $temp_limit + sqlite3_exec_nr [rbu db 1] "PRAGMA cache_size = $cachesize" + for {set i 0} {$i < $stepsize} {incr i} { + set rc [rbu step] + set ::A([rbu temp_size]) 1 + if {$rc!="SQLITE_OK"} break + } + set res [list [catch {rbu close} msg] $msg] + if {$res != "0 SQLITE_OK"} break + } + set res +} + +do_test 1.1.0 { setup_databases } {} + +do_test 1.1.1 { + unset -nocomplain ::A + run_rbu_cachesize test.db test.db2 10 0 +} {0 SQLITE_DONE} + +do_test 1.1.2 { llength [array names ::A] } 3 + +do_test 1.1.3 { + foreach {a0 a1 a2} [lsort -integer [array names ::A]] {} + list [expr $a0==0] \ + [expr $a1>1048576] [expr $a1<1200000] \ + [expr $a2>1500000] [expr $a2<1700000] +} {1 1 1 1 1} + +do_test 1.2.1 { + setup_databases + run_rbu_cachesize test.db test.db2 10 1000000 +} {1 SQLITE_FULL} +do_test 1.2.2 { info commands rbu } {} + +do_test 1.3.1 { + setup_databases + run_rbu_cachesize test.db test.db2 10 1300000 +} {1 SQLITE_FULL} +do_test 1.3.2 { info commands rbu } {} + +do_test 1.4.1 { + setup_databases + run_rbu_cachesize test.db test.db2 10 1800000 +} {0 SQLITE_DONE} +do_test 1.4.2 { info commands rbu } {} + +do_test 1.5.1 { + setup_databases + unset -nocomplain ::A + step_rbu_cachesize test.db test.db2 1000 10 2400000 +} {0 SQLITE_DONE} +do_test 1.5.2 { info commands rbu } {} + +do_test 1.6.1 { + setup_databases + unset -nocomplain ::A + step_rbu_cachesize test.db test.db2 1000 10 1400000 +} {1 SQLITE_FULL} +do_test 1.6.2 { info commands rbu } {} + +finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 033127853b..cd2f96c51b 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -96,6 +96,13 @@ /* Maximum number of prepared UPDATE statements held by this module */ #define SQLITE_RBU_UPDATE_CACHESIZE 16 +/* Delta checksums disabled by default. Compile with -DRBU_ENABLE_DELTA_CKSUM +** to enable checksum verification. +*/ +#ifndef RBU_ENABLE_DELTA_CKSUM +# define RBU_ENABLE_DELTA_CKSUM 0 +#endif + /* ** Swap two objects of type TYPE. */ @@ -146,6 +153,10 @@ ** ** RBU_STATE_OALSZ: ** Valid if STAGE==1. The size in bytes of the *-oal file. +** +** RBU_STATE_DATATBL: +** Only valid if STAGE==1. The RBU database name of the table +** currently being read. */ #define RBU_STATE_STAGE 1 #define RBU_STATE_TBL 2 @@ -156,6 +167,7 @@ #define RBU_STATE_COOKIE 7 #define RBU_STATE_OALSZ 8 #define RBU_STATE_PHASEONESTEP 9 +#define RBU_STATE_DATATBL 10 #define RBU_STAGE_OAL 1 #define RBU_STAGE_MOVE 2 @@ -198,6 +210,7 @@ typedef sqlite3_int64 i64; struct RbuState { int eStage; char *zTbl; + char *zDataTbl; char *zIdx; i64 iWalCksum; int nRow; @@ -371,6 +384,8 @@ struct sqlite3rbu { int pgsz; u8 *aBuf; i64 iWalCksum; + i64 szTemp; /* Current size of all temp files in use */ + i64 szTempLimit; /* Total size limit for temp files */ /* Used in RBU vacuum mode only */ int nRbu; /* Number of RBU VFS in the stack */ @@ -379,23 +394,34 @@ struct sqlite3rbu { /* ** An rbu VFS is implemented using an instance of this structure. +** +** Variable pRbu is only non-NULL for automatically created RBU VFS objects. +** It is NULL for RBU VFS objects created explicitly using +** sqlite3rbu_create_vfs(). It is used to track the total amount of temp +** space used by the RBU handle. */ struct rbu_vfs { sqlite3_vfs base; /* rbu VFS shim methods */ sqlite3_vfs *pRealVfs; /* Underlying VFS */ sqlite3_mutex *mutex; /* Mutex to protect pMain */ - rbu_file *pMain; /* Linked list of main db files */ + sqlite3rbu *pRbu; /* Owner RBU object */ + rbu_file *pMain; /* List of main db files */ + rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */ }; /* ** Each file opened by an rbu VFS is represented by an instance of ** the following structure. +** +** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable +** "sz" is set to the current size of the database file. */ struct rbu_file { sqlite3_file base; /* sqlite3_file methods */ sqlite3_file *pReal; /* Underlying file handle */ rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ + i64 sz; /* Size of file in bytes (temp only) */ int openFlags; /* Flags this file was opened with */ u32 iCookie; /* Cookie value for main db files */ @@ -409,6 +435,7 @@ struct rbu_file { const char *zWal; /* Wal filename for this main db file */ rbu_file *pWalFd; /* Wal file descriptor for this main db */ rbu_file *pMainNext; /* Next MAIN_DB file */ + rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */ }; /* @@ -458,6 +485,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ return v; } +#if RBU_ENABLE_DELTA_CKSUM /* ** Compute a 32-bit checksum on the N-byte buffer. Return the result. */ @@ -492,6 +520,7 @@ static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){ } return sum3; } +#endif /* ** Apply a delta. @@ -522,7 +551,7 @@ static int rbuDeltaApply( ){ unsigned int limit; unsigned int total = 0; -#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST +#if RBU_ENABLE_DELTA_CKSUM char *zOrigOut = zOut; #endif @@ -577,7 +606,7 @@ static int rbuDeltaApply( case ';': { zDelta++; lenDelta--; zOut[0] = 0; -#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST +#if RBU_ENABLE_DELTA_CKSUM if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){ /* ERROR: bad checksum */ return -1; @@ -1785,7 +1814,7 @@ static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){ int iCid = sqlite3_column_int(pXInfo, 1); int bDesc = sqlite3_column_int(pXInfo, 3); const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); - zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, + zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, iCid, pIter->azTblType[iCid], zCollate ); zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":""); @@ -1846,7 +1875,7 @@ static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){ ** "PRIMARY KEY" to the imposter table column declaration. */ zPk = "PRIMARY KEY "; } - zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", + zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s", zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl, (pIter->abNotNull[iCol] ? " NOT NULL" : "") ); @@ -2247,6 +2276,7 @@ static sqlite3 *rbuOpenDbhandle( static void rbuFreeState(RbuState *p){ if( p ){ sqlite3_free(p->zTbl); + sqlite3_free(p->zDataTbl); sqlite3_free(p->zIdx); sqlite3_free(p); } @@ -2317,6 +2347,10 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); break; + case RBU_STATE_DATATBL: + pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + default: rc = SQLITE_CORRUPT; break; @@ -3091,7 +3125,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " - "(%d, %lld) ", + "(%d, %lld), " + "(%d, %Q) ", p->zStateDb, RBU_STATE_STAGE, eStage, RBU_STATE_TBL, p->objiter.zTbl, @@ -3101,7 +3136,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ RBU_STATE_CKPT, p->iWalCksum, RBU_STATE_COOKIE, (i64)pFd->iCookie, RBU_STATE_OALSZ, p->iOalSz, - RBU_STATE_PHASEONESTEP, p->nPhaseOneStep + RBU_STATE_PHASEONESTEP, p->nPhaseOneStep, + RBU_STATE_DATATBL, p->objiter.zDataTbl ) ); assert( pInsert==0 || rc==SQLITE_OK ); @@ -3357,7 +3393,8 @@ static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){ while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup || rbuStrCompare(pIter->zIdx, pState->zIdx) - || rbuStrCompare(pIter->zTbl, pState->zTbl) + || (pState->zDataTbl==0 && rbuStrCompare(pIter->zTbl, pState->zTbl)) + || (pState->zDataTbl && rbuStrCompare(pIter->zDataTbl, pState->zDataTbl)) )){ rc = rbuObjIterNext(p, pIter); } @@ -3409,6 +3446,7 @@ static void rbuCreateVfs(sqlite3rbu *p){ sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd); assert( pVfs ); p->zVfsName = pVfs->zName; + ((rbu_vfs*)pVfs)->pRbu = p; } } @@ -3781,6 +3819,7 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){ /* Close the open database handle and VFS object. */ sqlite3_close(p->dbRbu); sqlite3_close(p->dbMain); + assert( p->szTemp==0 ); rbuDeleteVfs(p); sqlite3_free(p->aBuf); sqlite3_free(p->aFrame); @@ -3968,6 +4007,7 @@ int sqlite3rbu_savestate(sqlite3rbu *p){ */ static void rbuUnlockShm(rbu_file *p){ + assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); if( p->pRbu ){ int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock; int i; @@ -3980,6 +4020,81 @@ static void rbuUnlockShm(rbu_file *p){ } } +/* +*/ +static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){ + sqlite3rbu *pRbu = pFd->pRbu; + i64 nDiff = nNew - pFd->sz; + pRbu->szTemp += nDiff; + pFd->sz = nNew; + assert( pRbu->szTemp>=0 ); + if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL; + return SQLITE_OK; +} + +/* +** Add an item to the main-db lists, if it is not already present. +** +** There are two main-db lists. One for all file descriptors, and one +** for all file descriptors with rbu_file.pDb!=0. If the argument has +** rbu_file.pDb!=0, then it is assumed to already be present on the +** main list and is only added to the pDb!=0 list. +*/ +static void rbuMainlistAdd(rbu_file *p){ + rbu_vfs *pRbuVfs = p->pRbuVfs; + rbu_file *pIter; + assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) ); + sqlite3_mutex_enter(pRbuVfs->mutex); + if( p->pRbu==0 ){ + for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext); + p->pMainNext = pRbuVfs->pMain; + pRbuVfs->pMain = p; + }else{ + for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){} + if( pIter==0 ){ + p->pMainRbuNext = pRbuVfs->pMainRbu; + pRbuVfs->pMainRbu = p; + } + } + sqlite3_mutex_leave(pRbuVfs->mutex); +} + +/* +** Remove an item from the main-db lists. +*/ +static void rbuMainlistRemove(rbu_file *p){ + rbu_file **pp; + sqlite3_mutex_enter(p->pRbuVfs->mutex); + for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){} + if( *pp ) *pp = p->pMainNext; + p->pMainNext = 0; + for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){} + if( *pp ) *pp = p->pMainRbuNext; + p->pMainRbuNext = 0; + sqlite3_mutex_leave(p->pRbuVfs->mutex); +} + +/* +** Given that zWal points to a buffer containing a wal file name passed to +** either the xOpen() or xAccess() VFS method, search the main-db list for +** a file-handle opened by the same database connection on the corresponding +** database file. +** +** If parameter bRbu is true, only search for file-descriptors with +** rbu_file.pDb!=0. +*/ +static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){ + rbu_file *pDb; + sqlite3_mutex_enter(pRbuVfs->mutex); + if( bRbu ){ + for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){} + }else{ + for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} + } + sqlite3_mutex_leave(pRbuVfs->mutex); + return pDb; +} + /* ** Close an rbu file. */ @@ -3997,14 +4112,14 @@ static int rbuVfsClose(sqlite3_file *pFile){ sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ - rbu_file **pp; - sqlite3_mutex_enter(p->pRbuVfs->mutex); - for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext)); - *pp = p->pMainNext; - sqlite3_mutex_leave(p->pRbuVfs->mutex); + rbuMainlistRemove(p); rbuUnlockShm(p); p->pReal->pMethods->xShmUnmap(p->pReal, 0); } + else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ + rbuUpdateTempSize(p, 0); + } + assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p ); /* Close the underlying file handle */ rc = p->pReal->pMethods->xClose(p->pReal); @@ -4122,11 +4237,19 @@ static int rbuVfsWrite( assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); rc = rbuCaptureDbWrite(p->pRbu, iOfst); }else{ - if( pRbu && pRbu->eStage==RBU_STAGE_OAL - && (p->openFlags & SQLITE_OPEN_WAL) - && iOfst>=pRbu->iOalSz - ){ - pRbu->iOalSz = iAmt + iOfst; + if( pRbu ){ + if( pRbu->eStage==RBU_STAGE_OAL + && (p->openFlags & SQLITE_OPEN_WAL) + && iOfst>=pRbu->iOalSz + ){ + pRbu->iOalSz = iAmt + iOfst; + }else if( p->openFlags & SQLITE_OPEN_DELETEONCLOSE ){ + i64 szNew = iAmt+iOfst; + if( szNew>p->sz ){ + rc = rbuUpdateTempSize(p, szNew); + if( rc!=SQLITE_OK ) return rc; + } + } } rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ @@ -4145,6 +4268,10 @@ static int rbuVfsWrite( */ static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){ rbu_file *p = (rbu_file*)pFile; + if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ + int rc = rbuUpdateTempSize(p, size); + if( rc!=SQLITE_OK ) return rc; + } return p->pReal->pMethods->xTruncate(p->pReal, size); } @@ -4251,6 +4378,9 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){ }else if( rc==SQLITE_NOTFOUND ){ pRbu->pTargetFd = p; p->pRbu = pRbu; + if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ + rbuMainlistAdd(p); + } if( p->pWalFd ) p->pWalFd->pRbu = pRbu; rc = SQLITE_OK; } @@ -4412,20 +4542,6 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){ return rc; } -/* -** Given that zWal points to a buffer containing a wal file name passed to -** either the xOpen() or xAccess() VFS method, return a pointer to the -** file-handle opened by the same database connection on the corresponding -** database file. -*/ -static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){ - rbu_file *pDb; - sqlite3_mutex_enter(pRbuVfs->mutex); - for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} - sqlite3_mutex_leave(pRbuVfs->mutex); - return pDb; -} - /* ** A main database named zName has just been opened. The following ** function returns a pointer to a buffer owned by SQLite that contains @@ -4504,7 +4620,7 @@ static int rbuVfsOpen( pFd->zWal = rbuMainToWal(zName, flags); } else if( flags & SQLITE_OPEN_WAL ){ - rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName); + rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); if( pDb ){ if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ /* This call is to open a *-wal file. Intead, open the *-oal. This @@ -4534,6 +4650,8 @@ static int rbuVfsOpen( pDb->pWalFd = pFd; } } + }else{ + pFd->pRbu = pRbuVfs->pRbu; } if( oflags & SQLITE_OPEN_MAIN_DB @@ -4554,10 +4672,7 @@ static int rbuVfsOpen( ** mutex protected linked list of all such files. */ pFile->pMethods = &rbuvfs_io_methods; if( flags & SQLITE_OPEN_MAIN_DB ){ - sqlite3_mutex_enter(pRbuVfs->mutex); - pFd->pMainNext = pRbuVfs->pMain; - pRbuVfs->pMain = pFd; - sqlite3_mutex_leave(pRbuVfs->mutex); + rbuMainlistAdd(pFd); } }else{ sqlite3_free(pFd->zDel); @@ -4605,7 +4720,7 @@ static int rbuVfsAccess( ** file opened instead. */ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ - rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath); + rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1); if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ if( *pResOut ){ rc = SQLITE_CANTOPEN; @@ -4801,6 +4916,20 @@ int sqlite3rbu_create_vfs(const char *zName, const char *zParent){ return rc; } +/* +** Configure the aggregate temp file size limit for this RBU handle. +*/ +sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu *pRbu, sqlite3_int64 n){ + if( n>=0 ){ + pRbu->szTempLimit = n; + } + return pRbu->szTempLimit; +} + +sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){ + return pRbu->szTemp; +} + /**************************************************************************/ diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index 2f038fd8fd..1acbcca469 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -352,6 +352,28 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( const char *zState ); +/* +** Configure a limit for the amount of temp space that may be used by +** the RBU handle passed as the first argument. The new limit is specified +** in bytes by the second parameter. If it is positive, the limit is updated. +** If the second parameter to this function is passed zero, then the limit +** is removed entirely. If the second parameter is negative, the limit is +** not modified (this is useful for querying the current limit). +** +** In all cases the returned value is the current limit in bytes (zero +** indicates unlimited). +** +** If the temp space limit is exceeded during operation, an SQLITE_FULL +** error is returned. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64); + +/* +** Return the current amount of temp file space, in bytes, currently used by +** the RBU handle passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*); + /* ** Internally, each RBU connection uses a separate SQLite database ** connection to access the target and rbu update databases. This diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index fba90dcdc4..e0b4d77af0 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -69,16 +69,19 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd( int nArg; const char *zUsage; } aCmd[] = { - {"step", 2, ""}, /* 0 */ - {"close", 2, ""}, /* 1 */ - {"create_rbu_delta", 2, ""}, /* 2 */ - {"savestate", 2, ""}, /* 3 */ - {"dbMain_eval", 3, "SQL"}, /* 4 */ - {"bp_progress", 2, ""}, /* 5 */ - {"db", 3, "RBU"}, /* 6 */ - {"state", 2, ""}, /* 7 */ - {"progress", 2, ""}, /* 8 */ - {"close_no_error", 2, ""}, /* 9 */ + {"step", 2, ""}, /* 0 */ + {"close", 2, ""}, /* 1 */ + {"create_rbu_delta", 2, ""}, /* 2 */ + {"savestate", 2, ""}, /* 3 */ + {"dbMain_eval", 3, "SQL"}, /* 4 */ + {"bp_progress", 2, ""}, /* 5 */ + {"db", 3, "RBU"}, /* 6 */ + {"state", 2, ""}, /* 7 */ + {"progress", 2, ""}, /* 8 */ + {"close_no_error", 2, ""}, /* 9 */ + {"temp_size_limit", 3, "LIMIT"}, /* 10 */ + {"temp_size", 2, ""}, /* 11 */ + {"dbRbu_eval", 3, "SQL"}, /* 12 */ {0,0,0} }; int iCmd; @@ -144,8 +147,9 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd( break; } - case 4: /* dbMain_eval */ { - sqlite3 *db = sqlite3rbu_db(pRbu, 0); + case 12: /* dbRbu_eval */ + case 4: /* dbMain_eval */ { + sqlite3 *db = sqlite3rbu_db(pRbu, (iCmd==12)); int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0); if( rc!=SQLITE_OK ){ Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1)); @@ -193,6 +197,22 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd( Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nStep)); break; } + + case 10: /* temp_size_limit */ { + sqlite3_int64 nLimit; + if( Tcl_GetWideIntFromObj(interp, objv[2], &nLimit) ){ + ret = TCL_ERROR; + }else{ + nLimit = sqlite3rbu_temp_size_limit(pRbu, nLimit); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nLimit)); + } + break; + } + case 11: /* temp_size */ { + sqlite3_int64 sz = sqlite3rbu_temp_size(pRbu); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sz)); + break; + } default: /* seems unlikely */ assert( !"cannot happen" ); diff --git a/ext/repair/README.md b/ext/repair/README.md new file mode 100644 index 0000000000..927ceb7c44 --- /dev/null +++ b/ext/repair/README.md @@ -0,0 +1,16 @@ +This folder contains extensions and utility programs intended to analyze +live database files, detect problems, and possibly fix them. + +As SQLite is being used on larger and larger databases, database sizes +are growing into the terabyte range. At that size, hardware malfunctions +and/or cosmic rays will occasionally corrupt a database file. Detecting +problems and fixing errors a terabyte-sized databases can take hours or days, +and it is undesirable to take applications that depend on the databases +off-line for such a long time. +The utilities in the folder are intended to provide mechanisms for +detecting and fixing problems in large databases while those databases +are in active use. + +The utilities and extensions in this folder are experimental and under +active development at the time of this writing (2017-10-12). If and when +they stabilize, this README will be updated to reflect that fact. diff --git a/ext/repair/checkfreelist.c b/ext/repair/checkfreelist.c new file mode 100644 index 0000000000..990be4afa7 --- /dev/null +++ b/ext/repair/checkfreelist.c @@ -0,0 +1,299 @@ +/* +** 2017 October 11 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This module exports a single C function: +** +** int sqlite3_check_freelist(sqlite3 *db, const char *zDb); +** +** This function checks the free-list in database zDb (one of "main", +** "temp", etc.) and reports any errors by invoking the sqlite3_log() +** function. It returns SQLITE_OK if successful, or an SQLite error +** code otherwise. It is not an error if the free-list is corrupted but +** no IO or OOM errors occur. +** +** If this file is compiled and loaded as an SQLite loadable extension, +** it adds an SQL function "checkfreelist" to the database handle, to +** be invoked as follows: +** +** SELECT checkfreelist(); +** +** This function performs the same checks as sqlite3_check_freelist(), +** except that it returns all error messages as a single text value, +** separated by newline characters. If the freelist is not corrupted +** in any way, an empty string is returned. +** +** To compile this module for use as an SQLite loadable extension: +** +** gcc -Os -fPIC -shared checkfreelist.c -o checkfreelist.so +*/ + +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 + +#ifndef SQLITE_AMALGAMATION +# include +# include +# include +# include +# define ALWAYS(X) 1 +# define NEVER(X) 0 + typedef unsigned char u8; + typedef unsigned short u16; + typedef unsigned int u32; +#define get4byte(x) ( \ + ((u32)((x)[0])<<24) + \ + ((u32)((x)[1])<<16) + \ + ((u32)((x)[2])<<8) + \ + ((u32)((x)[3])) \ +) +#endif + +/* +** Execute a single PRAGMA statement and return the integer value returned +** via output parameter (*pnOut). +** +** The SQL statement passed as the third argument should be a printf-style +** format string containing a single "%s" which will be replace by the +** value passed as the second argument. e.g. +** +** sqlGetInteger(db, "main", "PRAGMA %s.page_count", pnOut) +** +** executes "PRAGMA main.page_count" and stores the results in (*pnOut). +*/ +static int sqlGetInteger( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Database name ("main", "temp" etc.) */ + const char *zFmt, /* SQL statement format */ + u32 *pnOut /* OUT: Integer value */ +){ + int rc, rc2; + char *zSql; + sqlite3_stmt *pStmt = 0; + int bOk = 0; + + zSql = sqlite3_mprintf(zFmt, zDb); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + *pnOut = (u32)sqlite3_column_int(pStmt, 0); + bOk = 1; + } + + rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_ERROR; + return rc; +} + +/* +** Argument zFmt must be a printf-style format string and must be +** followed by its required arguments. If argument pzOut is NULL, +** then the results of printf()ing the format string are passed to +** sqlite3_log(). Otherwise, they are appended to the string +** at (*pzOut). +*/ +static int checkFreelistError(char **pzOut, const char *zFmt, ...){ + int rc = SQLITE_OK; + char *zErr = 0; + va_list ap; + + va_start(ap, zFmt); + zErr = sqlite3_vmprintf(zFmt, ap); + if( zErr==0 ){ + rc = SQLITE_NOMEM; + }else{ + if( pzOut ){ + *pzOut = sqlite3_mprintf("%s%z%s", *pzOut?"\n":"", *pzOut, zErr); + if( *pzOut==0 ) rc = SQLITE_NOMEM; + }else{ + sqlite3_log(SQLITE_ERROR, "checkfreelist: %s", zErr); + } + sqlite3_free(zErr); + } + va_end(ap); + return rc; +} + +static int checkFreelist( + sqlite3 *db, + const char *zDb, + char **pzOut +){ + /* This query returns one row for each page on the free list. Each row has + ** two columns - the page number and page content. */ + const char *zTrunk = + "WITH freelist_trunk(i, d, n) AS (" + "SELECT 1, NULL, sqlite_readint32(data, 32) " + "FROM sqlite_dbpage(:1) WHERE pgno=1 " + "UNION ALL " + "SELECT n, data, sqlite_readint32(data) " + "FROM freelist_trunk, sqlite_dbpage(:1) WHERE pgno=n " + ")" + "SELECT i, d FROM freelist_trunk WHERE i!=1;"; + + int rc, rc2; /* Return code */ + sqlite3_stmt *pTrunk = 0; /* Compilation of zTrunk */ + u32 nPage = 0; /* Number of pages in db */ + u32 nExpected = 0; /* Expected number of free pages */ + u32 nFree = 0; /* Number of pages on free list */ + + if( zDb==0 ) zDb = "main"; + + if( (rc = sqlGetInteger(db, zDb, "PRAGMA %s.page_count", &nPage)) + || (rc = sqlGetInteger(db, zDb, "PRAGMA %s.freelist_count", &nExpected)) + ){ + return rc; + } + + rc = sqlite3_prepare_v2(db, zTrunk, -1, &pTrunk, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_text(pTrunk, 1, zDb, -1, SQLITE_STATIC); + while( rc==SQLITE_OK && sqlite3_step(pTrunk)==SQLITE_ROW ){ + u32 i; + u32 iTrunk = (u32)sqlite3_column_int(pTrunk, 0); + const u8 *aData = (const u8*)sqlite3_column_blob(pTrunk, 1); + u32 nData = (u32)sqlite3_column_bytes(pTrunk, 1); + u32 iNext = get4byte(&aData[0]); + u32 nLeaf = get4byte(&aData[4]); + + if( nLeaf>((nData/4)-2-6) ){ + rc = checkFreelistError(pzOut, + "leaf count out of range (%d) on trunk page %d", + (int)nLeaf, (int)iTrunk + ); + nLeaf = (nData/4) - 2 - 6; + } + + nFree += 1+nLeaf; + if( iNext>nPage ){ + rc = checkFreelistError(pzOut, + "trunk page %d is out of range", (int)iNext + ); + } + + for(i=0; rc==SQLITE_OK && inPage ){ + rc = checkFreelistError(pzOut, + "leaf page %d is out of range (child %d of trunk page %d)", + (int)iLeaf, (int)i, (int)iTrunk + ); + } + } + } + + if( rc==SQLITE_OK && nFree!=nExpected ){ + rc = checkFreelistError(pzOut, + "free-list count mismatch: actual=%d header=%d", + (int)nFree, (int)nExpected + ); + } + + rc2 = sqlite3_finalize(pTrunk); + if( rc==SQLITE_OK ) rc = rc2; + return rc; +} + +int sqlite3_check_freelist(sqlite3 *db, const char *zDb){ + return checkFreelist(db, zDb, 0); +} + +static void checkfreelist_function( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + const char *zDb; + int rc; + char *zOut = 0; + sqlite3 *db = sqlite3_context_db_handle(pCtx); + + assert( nArg==1 ); + zDb = (const char*)sqlite3_value_text(apArg[0]); + rc = checkFreelist(db, zDb, &zOut); + if( rc==SQLITE_OK ){ + sqlite3_result_text(pCtx, zOut?zOut:"ok", -1, SQLITE_TRANSIENT); + }else{ + sqlite3_result_error_code(pCtx, rc); + } + + sqlite3_free(zOut); +} + +/* +** An SQL function invoked as follows: +** +** sqlite_readint32(BLOB) -- Decode 32-bit integer from start of blob +*/ +static void readint_function( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + const u8 *zBlob; + int nBlob; + int iOff = 0; + u32 iRet = 0; + + if( nArg!=1 && nArg!=2 ){ + sqlite3_result_error( + pCtx, "wrong number of arguments to function sqlite_readint32()", -1 + ); + return; + } + if( nArg==2 ){ + iOff = sqlite3_value_int(apArg[1]); + } + + zBlob = sqlite3_value_blob(apArg[0]); + nBlob = sqlite3_value_bytes(apArg[0]); + + if( nBlob>=(iOff+4) ){ + iRet = get4byte(&zBlob[iOff]); + } + + sqlite3_result_int64(pCtx, (sqlite3_int64)iRet); +} + +/* +** Register the SQL functions. +*/ +static int cflRegister(sqlite3 *db){ + int rc = sqlite3_create_function( + db, "sqlite_readint32", -1, SQLITE_UTF8, 0, readint_function, 0, 0 + ); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3_create_function( + db, "checkfreelist", 1, SQLITE_UTF8, 0, checkfreelist_function, 0, 0 + ); + return rc; +} + +/* +** Extension load function. +*/ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_checkfreelist_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi); + return cflRegister(db); +} diff --git a/ext/repair/checkindex.c b/ext/repair/checkindex.c new file mode 100644 index 0000000000..58706c1aab --- /dev/null +++ b/ext/repair/checkindex.c @@ -0,0 +1,927 @@ +/* +** 2017 October 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 + +/* +** Stuff that is available inside the amalgamation, but which we need to +** declare ourselves if this module is compiled separately. +*/ +#ifndef SQLITE_AMALGAMATION +# include +# include +# include +# include +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +#define get4byte(x) ( \ + ((u32)((x)[0])<<24) + \ + ((u32)((x)[1])<<16) + \ + ((u32)((x)[2])<<8) + \ + ((u32)((x)[3])) \ +) +#endif + +typedef struct CidxTable CidxTable; +typedef struct CidxCursor CidxCursor; + +struct CidxTable { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; +}; + +struct CidxCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_int64 iRowid; /* Row number of the output */ + char *zIdxName; /* Copy of the index_name parameter */ + char *zAfterKey; /* Copy of the after_key parameter */ + sqlite3_stmt *pStmt; /* SQL statement that generates the output */ +}; + +typedef struct CidxColumn CidxColumn; +struct CidxColumn { + char *zExpr; /* Text for indexed expression */ + int bDesc; /* True for DESC columns, otherwise false */ + int bKey; /* Part of index, not PK */ +}; + +typedef struct CidxIndex CidxIndex; +struct CidxIndex { + char *zWhere; /* WHERE clause, if any */ + int nCol; /* Elements in aCol[] array */ + CidxColumn aCol[1]; /* Array of indexed columns */ +}; + +static void *cidxMalloc(int *pRc, int n){ + void *pRet = 0; + assert( n!=0 ); + if( *pRc==SQLITE_OK ){ + pRet = sqlite3_malloc(n); + if( pRet ){ + memset(pRet, 0, n); + }else{ + *pRc = SQLITE_NOMEM; + } + } + return pRet; +} + +static void cidxCursorError(CidxCursor *pCsr, const char *zFmt, ...){ + va_list ap; + va_start(ap, zFmt); + assert( pCsr->base.pVtab->zErrMsg==0 ); + pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); + va_end(ap); +} + +/* +** Connect to the incremental_index_check virtual table. +*/ +static int cidxConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + int rc = SQLITE_OK; + CidxTable *pRet; + +#define IIC_ERRMSG 0 +#define IIC_CURRENT_KEY 1 +#define IIC_INDEX_NAME 2 +#define IIC_AFTER_KEY 3 +#define IIC_SCANNER_SQL 4 + rc = sqlite3_declare_vtab(db, + "CREATE TABLE xyz(" + " errmsg TEXT," /* Error message or NULL if everything is ok */ + " current_key TEXT," /* SQLite quote() text of key values */ + " index_name HIDDEN," /* IN: name of the index being scanned */ + " after_key HIDDEN," /* IN: Start scanning after this key */ + " scanner_sql HIDDEN" /* debuggingn info: SQL used for scanner */ + ")" + ); + pRet = cidxMalloc(&rc, sizeof(CidxTable)); + if( pRet ){ + pRet->db = db; + } + + *ppVtab = (sqlite3_vtab*)pRet; + return rc; +} + +/* +** Disconnect from or destroy an incremental_index_check virtual table. +*/ +static int cidxDisconnect(sqlite3_vtab *pVtab){ + CidxTable *pTab = (CidxTable*)pVtab; + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* +** idxNum and idxStr are not used. There are only three possible plans, +** which are all distinguished by the number of parameters. +** +** No parameters: A degenerate plan. The result is zero rows. +** 1 Parameter: Scan all of the index starting with first entry +** 2 parameters: Scan the index starting after the "after_key". +** +** Provide successively smaller costs for each of these plans to encourage +** the query planner to select the one with the most parameters. +*/ +static int cidxBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pInfo){ + int iIdxName = -1; + int iAfterKey = -1; + int i; + + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; + if( p->usable==0 ) continue; + if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + + if( p->iColumn==IIC_INDEX_NAME ){ + iIdxName = i; + } + if( p->iColumn==IIC_AFTER_KEY ){ + iAfterKey = i; + } + } + + if( iIdxName<0 ){ + pInfo->estimatedCost = 1000000000.0; + }else{ + pInfo->aConstraintUsage[iIdxName].argvIndex = 1; + pInfo->aConstraintUsage[iIdxName].omit = 1; + if( iAfterKey<0 ){ + pInfo->estimatedCost = 1000000.0; + }else{ + pInfo->aConstraintUsage[iAfterKey].argvIndex = 2; + pInfo->aConstraintUsage[iAfterKey].omit = 1; + pInfo->estimatedCost = 1000.0; + } + } + + return SQLITE_OK; +} + +/* +** Open a new btreeinfo cursor. +*/ +static int cidxOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + CidxCursor *pRet; + int rc = SQLITE_OK; + + pRet = cidxMalloc(&rc, sizeof(CidxCursor)); + + *ppCursor = (sqlite3_vtab_cursor*)pRet; + return rc; +} + +/* +** Close a btreeinfo cursor. +*/ +static int cidxClose(sqlite3_vtab_cursor *pCursor){ + CidxCursor *pCsr = (CidxCursor*)pCursor; + sqlite3_finalize(pCsr->pStmt); + sqlite3_free(pCsr->zIdxName); + sqlite3_free(pCsr->zAfterKey); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Move a btreeinfo cursor to the next entry in the file. +*/ +static int cidxNext(sqlite3_vtab_cursor *pCursor){ + CidxCursor *pCsr = (CidxCursor*)pCursor; + int rc = sqlite3_step(pCsr->pStmt); + if( rc!=SQLITE_ROW ){ + rc = sqlite3_finalize(pCsr->pStmt); + pCsr->pStmt = 0; + if( rc!=SQLITE_OK ){ + sqlite3 *db = ((CidxTable*)pCsr->base.pVtab)->db; + cidxCursorError(pCsr, "Cursor error: %s", sqlite3_errmsg(db)); + } + }else{ + pCsr->iRowid++; + rc = SQLITE_OK; + } + return rc; +} + +/* We have reached EOF if previous sqlite3_step() returned +** anything other than SQLITE_ROW; +*/ +static int cidxEof(sqlite3_vtab_cursor *pCursor){ + CidxCursor *pCsr = (CidxCursor*)pCursor; + return pCsr->pStmt==0; +} + +static char *cidxMprintf(int *pRc, const char *zFmt, ...){ + char *zRet = 0; + va_list ap; + va_start(ap, zFmt); + zRet = sqlite3_vmprintf(zFmt, ap); + if( *pRc==SQLITE_OK ){ + if( zRet==0 ){ + *pRc = SQLITE_NOMEM; + } + }else{ + sqlite3_free(zRet); + zRet = 0; + } + va_end(ap); + return zRet; +} + +static sqlite3_stmt *cidxPrepare( + int *pRc, CidxCursor *pCsr, const char *zFmt, ... +){ + sqlite3_stmt *pRet = 0; + char *zSql; + va_list ap; /* ... printf arguments */ + va_start(ap, zFmt); + + zSql = sqlite3_vmprintf(zFmt, ap); + if( *pRc==SQLITE_OK ){ + if( zSql==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + sqlite3 *db = ((CidxTable*)pCsr->base.pVtab)->db; + *pRc = sqlite3_prepare_v2(db, zSql, -1, &pRet, 0); + if( *pRc!=SQLITE_OK ){ + cidxCursorError(pCsr, "SQL error: %s", sqlite3_errmsg(db)); + } + } + } + sqlite3_free(zSql); + va_end(ap); + + return pRet; +} + +static void cidxFinalize(int *pRc, sqlite3_stmt *pStmt){ + int rc = sqlite3_finalize(pStmt); + if( *pRc==SQLITE_OK ) *pRc = rc; +} + +char *cidxStrdup(int *pRc, const char *zStr){ + char *zRet = 0; + if( *pRc==SQLITE_OK ){ + int n = (int)strlen(zStr); + zRet = cidxMalloc(pRc, n+1); + if( zRet ) memcpy(zRet, zStr, n+1); + } + return zRet; +} + +static void cidxFreeIndex(CidxIndex *pIdx){ + if( pIdx ){ + int i; + for(i=0; inCol; i++){ + sqlite3_free(pIdx->aCol[i].zExpr); + } + sqlite3_free(pIdx->zWhere); + sqlite3_free(pIdx); + } +} + +static int cidx_isspace(char c){ + return c==' ' || c=='\t' || c=='\r' || c=='\n'; +} + +static int cidx_isident(char c){ + return c<0 + || (c>='0' && c<='9') || (c>='a' && c<='z') + || (c>='A' && c<='Z') || c=='_'; +} + +#define CIDX_PARSE_EOF 0 +#define CIDX_PARSE_COMMA 1 /* "," */ +#define CIDX_PARSE_OPEN 2 /* "(" */ +#define CIDX_PARSE_CLOSE 3 /* ")" */ + +/* +** Argument zIn points into the start, middle or end of a CREATE INDEX +** statement. If argument pbDoNotTrim is non-NULL, then this function +** scans the input until it finds EOF, a comma (",") or an open or +** close parenthesis character. It then sets (*pzOut) to point to said +** character and returns a CIDX_PARSE_XXX constant as appropriate. The +** parser is smart enough that special characters inside SQL strings +** or comments are not returned for. +** +** Or, if argument pbDoNotTrim is NULL, then this function sets *pzOut +** to point to the first character of the string that is not whitespace +** or part of an SQL comment and returns CIDX_PARSE_EOF. +** +** Additionally, if pbDoNotTrim is not NULL and the element immediately +** before (*pzOut) is an SQL comment of the form "-- comment", then +** (*pbDoNotTrim) is set before returning. In all other cases it is +** cleared. +*/ +static int cidxFindNext( + const char *zIn, + const char **pzOut, + int *pbDoNotTrim /* OUT: True if prev is -- comment */ +){ + const char *z = zIn; + + while( 1 ){ + while( cidx_isspace(*z) ) z++; + if( z[0]=='-' && z[1]=='-' ){ + z += 2; + while( z[0]!='\n' ){ + if( z[0]=='\0' ) return CIDX_PARSE_EOF; + z++; + } + while( cidx_isspace(*z) ) z++; + if( pbDoNotTrim ) *pbDoNotTrim = 1; + }else + if( z[0]=='/' && z[1]=='*' ){ + z += 2; + while( z[0]!='*' || z[1]!='/' ){ + if( z[1]=='\0' ) return CIDX_PARSE_EOF; + z++; + } + z += 2; + }else{ + *pzOut = z; + if( pbDoNotTrim==0 ) return CIDX_PARSE_EOF; + switch( *z ){ + case '\0': + return CIDX_PARSE_EOF; + case '(': + return CIDX_PARSE_OPEN; + case ')': + return CIDX_PARSE_CLOSE; + case ',': + return CIDX_PARSE_COMMA; + + case '"': + case '\'': + case '`': { + char q = *z; + z++; + while( *z ){ + if( *z==q ){ + z++; + if( *z!=q ) break; + } + z++; + } + break; + } + + case '[': + while( *z++!=']' ); + break; + + default: + z++; + break; + } + *pbDoNotTrim = 0; + } + } + + assert( 0 ); + return -1; +} + +static int cidxParseSQL(CidxCursor *pCsr, CidxIndex *pIdx, const char *zSql){ + const char *z = zSql; + const char *z1; + int e; + int rc = SQLITE_OK; + int nParen = 1; + int bDoNotTrim = 0; + CidxColumn *pCol = pIdx->aCol; + + e = cidxFindNext(z, &z, &bDoNotTrim); + if( e!=CIDX_PARSE_OPEN ) goto parse_error; + z1 = z+1; + z++; + while( nParen>0 ){ + e = cidxFindNext(z, &z, &bDoNotTrim); + if( e==CIDX_PARSE_EOF ) goto parse_error; + if( (e==CIDX_PARSE_COMMA || e==CIDX_PARSE_CLOSE) && nParen==1 ){ + const char *z2 = z; + if( pCol->zExpr ) goto parse_error; + + if( bDoNotTrim==0 ){ + while( cidx_isspace(z[-1]) ) z--; + if( !sqlite3_strnicmp(&z[-3], "asc", 3) && 0==cidx_isident(z[-4]) ){ + z -= 3; + while( cidx_isspace(z[-1]) ) z--; + }else + if( !sqlite3_strnicmp(&z[-4], "desc", 4) && 0==cidx_isident(z[-5]) ){ + z -= 4; + while( cidx_isspace(z[-1]) ) z--; + } + while( cidx_isspace(z1[0]) ) z1++; + } + + pCol->zExpr = cidxMprintf(&rc, "%.*s", z-z1, z1); + pCol++; + z = z1 = z2+1; + } + if( e==CIDX_PARSE_OPEN ) nParen++; + if( e==CIDX_PARSE_CLOSE ) nParen--; + z++; + } + + /* Search for a WHERE clause */ + cidxFindNext(z, &z, 0); + if( 0==sqlite3_strnicmp(z, "where", 5) ){ + pIdx->zWhere = cidxMprintf(&rc, "%s\n", &z[5]); + }else if( z[0]!='\0' ){ + goto parse_error; + } + + return rc; + + parse_error: + cidxCursorError(pCsr, "Parse error in: %s", zSql); + return SQLITE_ERROR; +} + +static int cidxLookupIndex( + CidxCursor *pCsr, /* Cursor object */ + const char *zIdx, /* Name of index to look up */ + CidxIndex **ppIdx, /* OUT: Description of columns */ + char **pzTab /* OUT: Table name */ +){ + int rc = SQLITE_OK; + char *zTab = 0; + CidxIndex *pIdx = 0; + + sqlite3_stmt *pFindTab = 0; + sqlite3_stmt *pInfo = 0; + + /* Find the table for this index. */ + pFindTab = cidxPrepare(&rc, pCsr, + "SELECT tbl_name, sql FROM sqlite_master WHERE name=%Q AND type='index'", + zIdx + ); + if( rc==SQLITE_OK && sqlite3_step(pFindTab)==SQLITE_ROW ){ + const char *zSql = (const char*)sqlite3_column_text(pFindTab, 1); + zTab = cidxStrdup(&rc, (const char*)sqlite3_column_text(pFindTab, 0)); + + pInfo = cidxPrepare(&rc, pCsr, "PRAGMA index_xinfo(%Q)", zIdx); + if( rc==SQLITE_OK ){ + int nAlloc = 0; + int iCol = 0; + + while( sqlite3_step(pInfo)==SQLITE_ROW ){ + const char *zName = (const char*)sqlite3_column_text(pInfo, 2); + const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); + CidxColumn *p; + if( zName==0 ) zName = "rowid"; + if( iCol==nAlloc ){ + int nByte = sizeof(CidxIndex) + sizeof(CidxColumn)*(nAlloc+8); + pIdx = (CidxIndex*)sqlite3_realloc(pIdx, nByte); + nAlloc += 8; + } + p = &pIdx->aCol[iCol++]; + p->bDesc = sqlite3_column_int(pInfo, 3); + p->bKey = sqlite3_column_int(pInfo, 5); + if( zSql==0 || p->bKey==0 ){ + p->zExpr = cidxMprintf(&rc, "\"%w\" COLLATE %s",zName,zColl); + }else{ + p->zExpr = 0; + } + pIdx->nCol = iCol; + pIdx->zWhere = 0; + } + cidxFinalize(&rc, pInfo); + } + + if( rc==SQLITE_OK && zSql ){ + rc = cidxParseSQL(pCsr, pIdx, zSql); + } + } + + cidxFinalize(&rc, pFindTab); + if( rc==SQLITE_OK && zTab==0 ){ + rc = SQLITE_ERROR; + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(zTab); + cidxFreeIndex(pIdx); + }else{ + *pzTab = zTab; + *ppIdx = pIdx; + } + + return rc; +} + +static int cidxDecodeAfter( + CidxCursor *pCsr, + int nCol, + const char *zAfterKey, + char ***pazAfter +){ + char **azAfter; + int rc = SQLITE_OK; + int nAfterKey = (int)strlen(zAfterKey); + + azAfter = cidxMalloc(&rc, sizeof(char*)*nCol + nAfterKey+1); + if( rc==SQLITE_OK ){ + int i; + char *zCopy = (char*)&azAfter[nCol]; + char *p = zCopy; + memcpy(zCopy, zAfterKey, nAfterKey+1); + for(i=0; i='0' && *p<='9') + || *p=='.' || *p=='+' || *p=='-' || *p=='e' || *p=='E' + ){ + p++; + } + } + + while( *p==' ' ) p++; + if( *p!=(i==(nCol-1) ? '\0' : ',') ){ + goto parse_error; + } + *p++ = '\0'; + } + } + + *pazAfter = azAfter; + return rc; + + parse_error: + sqlite3_free(azAfter); + *pazAfter = 0; + cidxCursorError(pCsr, "%s", "error parsing after value"); + return SQLITE_ERROR; +} + +static char *cidxWhere( + int *pRc, CidxColumn *aCol, char **azAfter, int iGt, int bLastIsNull +){ + char *zRet = 0; + const char *zSep = ""; + int i; + + for(i=0; i"), + azAfter[iGt] + ); + }else{ + zRet = cidxMprintf(pRc, "%z%s(%s) IS NOT NULL", zRet, zSep,aCol[iGt].zExpr); + } + + return zRet; +} + +#define CIDX_CLIST_ALL 0 +#define CIDX_CLIST_ORDERBY 1 +#define CIDX_CLIST_CURRENT_KEY 2 +#define CIDX_CLIST_SUBWHERE 3 +#define CIDX_CLIST_SUBEXPR 4 + +/* +** This function returns various strings based on the contents of the +** CidxIndex structure and the eType parameter. +*/ +static char *cidxColumnList( + int *pRc, /* IN/OUT: Error code */ + const char *zIdx, + CidxIndex *pIdx, /* Indexed columns */ + int eType /* True to include ASC/DESC */ +){ + char *zRet = 0; + if( *pRc==SQLITE_OK ){ + const char *aDir[2] = {"", " DESC"}; + int i; + const char *zSep = ""; + + for(i=0; inCol; i++){ + CidxColumn *p = &pIdx->aCol[i]; + assert( pIdx->aCol[i].bDesc==0 || pIdx->aCol[i].bDesc==1 ); + switch( eType ){ + + case CIDX_CLIST_ORDERBY: + zRet = cidxMprintf(pRc, "%z%s%d%s", zRet, zSep, i+1, aDir[p->bDesc]); + zSep = ","; + break; + + case CIDX_CLIST_CURRENT_KEY: + zRet = cidxMprintf(pRc, "%z%squote(i%d)", zRet, zSep, i); + zSep = "||','||"; + break; + + case CIDX_CLIST_SUBWHERE: + if( p->bKey==0 ){ + zRet = cidxMprintf(pRc, "%z%s%s IS i.i%d", zRet, + zSep, p->zExpr, i + ); + zSep = " AND "; + } + break; + + case CIDX_CLIST_SUBEXPR: + if( p->bKey==1 ){ + zRet = cidxMprintf(pRc, "%z%s%s IS i.i%d", zRet, + zSep, p->zExpr, i + ); + zSep = " AND "; + } + break; + + default: + assert( eType==CIDX_CLIST_ALL ); + zRet = cidxMprintf(pRc, "%z%s(%s) AS i%d", zRet, zSep, p->zExpr, i); + zSep = ", "; + break; + } + } + } + + return zRet; +} + +/* +** Generate SQL (in memory obtained from sqlite3_malloc()) that will +** continue the index scan for zIdxName starting after zAfterKey. +*/ +int cidxGenerateScanSql( + CidxCursor *pCsr, /* The cursor which needs the new statement */ + const char *zIdxName, /* index to be scanned */ + const char *zAfterKey, /* start after this key, if not NULL */ + char **pzSqlOut /* OUT: Write the generated SQL here */ +){ + int rc; + char *zTab = 0; + char *zCurrentKey = 0; + char *zOrderBy = 0; + char *zSubWhere = 0; + char *zSubExpr = 0; + char *zSrcList = 0; + char **azAfter = 0; + CidxIndex *pIdx = 0; + + *pzSqlOut = 0; + rc = cidxLookupIndex(pCsr, zIdxName, &pIdx, &zTab); + + zOrderBy = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_ORDERBY); + zCurrentKey = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_CURRENT_KEY); + zSubWhere = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_SUBWHERE); + zSubExpr = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_SUBEXPR); + zSrcList = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_ALL); + + if( rc==SQLITE_OK && zAfterKey ){ + rc = cidxDecodeAfter(pCsr, pIdx->nCol, zAfterKey, &azAfter); + } + + if( rc==SQLITE_OK ){ + if( zAfterKey==0 ){ + *pzSqlOut = cidxMprintf(&rc, + "SELECT (SELECT %s FROM %Q AS t WHERE %s), %s " + "FROM (SELECT %s FROM %Q INDEXED BY %Q %s%sORDER BY %s) AS i", + zSubExpr, zTab, zSubWhere, zCurrentKey, + zSrcList, zTab, zIdxName, + (pIdx->zWhere ? "WHERE " : ""), (pIdx->zWhere ? pIdx->zWhere : ""), + zOrderBy + ); + }else{ + const char *zSep = ""; + char *zSql; + int i; + + zSql = cidxMprintf(&rc, + "SELECT (SELECT %s FROM %Q WHERE %s), %s FROM (", + zSubExpr, zTab, zSubWhere, zCurrentKey + ); + for(i=pIdx->nCol-1; i>=0; i--){ + int j; + if( pIdx->aCol[i].bDesc && azAfter[i]==0 ) continue; + for(j=0; j<2; j++){ + char *zWhere = cidxWhere(&rc, pIdx->aCol, azAfter, i, j); + zSql = cidxMprintf(&rc, "%z" + "%sSELECT * FROM (" + "SELECT %s FROM %Q INDEXED BY %Q WHERE %s%s%z ORDER BY %s" + ")", + zSql, zSep, zSrcList, zTab, zIdxName, + pIdx->zWhere ? pIdx->zWhere : "", + pIdx->zWhere ? " AND " : "", + zWhere, zOrderBy + ); + zSep = " UNION ALL "; + if( pIdx->aCol[i].bDesc==0 ) break; + } + } + *pzSqlOut = cidxMprintf(&rc, "%z) AS i", zSql); + } + } + + sqlite3_free(zTab); + sqlite3_free(zCurrentKey); + sqlite3_free(zOrderBy); + sqlite3_free(zSubWhere); + sqlite3_free(zSubExpr); + sqlite3_free(zSrcList); + cidxFreeIndex(pIdx); + sqlite3_free(azAfter); + return rc; +} + + +/* +** Position a cursor back to the beginning. +*/ +static int cidxFilter( + sqlite3_vtab_cursor *pCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + int rc = SQLITE_OK; + CidxCursor *pCsr = (CidxCursor*)pCursor; + const char *zIdxName = 0; + const char *zAfterKey = 0; + + sqlite3_free(pCsr->zIdxName); + pCsr->zIdxName = 0; + sqlite3_free(pCsr->zAfterKey); + pCsr->zAfterKey = 0; + sqlite3_finalize(pCsr->pStmt); + pCsr->pStmt = 0; + + if( argc>0 ){ + zIdxName = (const char*)sqlite3_value_text(argv[0]); + if( argc>1 ){ + zAfterKey = (const char*)sqlite3_value_text(argv[1]); + } + } + + if( zIdxName ){ + char *zSql = 0; + pCsr->zIdxName = sqlite3_mprintf("%s", zIdxName); + pCsr->zAfterKey = zAfterKey ? sqlite3_mprintf("%s", zAfterKey) : 0; + rc = cidxGenerateScanSql(pCsr, zIdxName, zAfterKey, &zSql); + if( zSql ){ + pCsr->pStmt = cidxPrepare(&rc, pCsr, "%z", zSql); + } + } + + if( pCsr->pStmt ){ + assert( rc==SQLITE_OK ); + rc = cidxNext(pCursor); + } + pCsr->iRowid = 1; + return rc; +} + +/* +** Return a column value. +*/ +static int cidxColumn( + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, + int iCol +){ + CidxCursor *pCsr = (CidxCursor*)pCursor; + assert( iCol>=IIC_ERRMSG && iCol<=IIC_SCANNER_SQL ); + switch( iCol ){ + case IIC_ERRMSG: { + const char *zVal = 0; + if( sqlite3_column_type(pCsr->pStmt, 0)==SQLITE_INTEGER ){ + if( sqlite3_column_int(pCsr->pStmt, 0)==0 ){ + zVal = "row data mismatch"; + } + }else{ + zVal = "row missing"; + } + sqlite3_result_text(ctx, zVal, -1, SQLITE_STATIC); + break; + } + case IIC_CURRENT_KEY: { + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, 1)); + break; + } + case IIC_INDEX_NAME: { + sqlite3_result_text(ctx, pCsr->zIdxName, -1, SQLITE_TRANSIENT); + break; + } + case IIC_AFTER_KEY: { + sqlite3_result_text(ctx, pCsr->zAfterKey, -1, SQLITE_TRANSIENT); + break; + } + case IIC_SCANNER_SQL: { + char *zSql = 0; + cidxGenerateScanSql(pCsr, pCsr->zIdxName, pCsr->zAfterKey, &zSql); + sqlite3_result_text(ctx, zSql, -1, sqlite3_free); + break; + } + } + return SQLITE_OK; +} + +/* Return the ROWID for the sqlite_btreeinfo table */ +static int cidxRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + CidxCursor *pCsr = (CidxCursor*)pCursor; + *pRowid = pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the virtual table modules with the database handle passed +** as the only argument. +*/ +static int ciInit(sqlite3 *db){ + static sqlite3_module cidx_module = { + 0, /* iVersion */ + 0, /* xCreate */ + cidxConnect, /* xConnect */ + cidxBestIndex, /* xBestIndex */ + cidxDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + cidxOpen, /* xOpen - open a cursor */ + cidxClose, /* xClose - close a cursor */ + cidxFilter, /* xFilter - configure scan constraints */ + cidxNext, /* xNext - advance a cursor */ + cidxEof, /* xEof - check for end of scan */ + cidxColumn, /* xColumn - read data */ + cidxRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + }; + return sqlite3_create_module(db, "incremental_index_check", &cidx_module, 0); +} + +/* +** Extension load function. +*/ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_checkindex_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi); + return ciInit(db); +} diff --git a/ext/repair/sqlite3_checker.c.in b/ext/repair/sqlite3_checker.c.in new file mode 100644 index 0000000000..76e9708787 --- /dev/null +++ b/ext/repair/sqlite3_checker.c.in @@ -0,0 +1,86 @@ +/* +** Read an SQLite database file and analyze its space utilization. Generate +** text on standard output. +*/ +#define TCLSH_INIT_PROC sqlite3_checker_init_proc +#define SQLITE_ENABLE_DBPAGE_VTAB 1 +#define SQLITE_ENABLE_JSON1 1 +#undef SQLITE_THREADSAFE +#define SQLITE_THREADSAFE 0 +#undef SQLITE_ENABLE_COLUMN_METADATA +#define SQLITE_OMIT_DECLTYPE 1 +#define SQLITE_OMIT_DEPRECATED 1 +#define SQLITE_OMIT_PROGRESS_CALLBACK 1 +#define SQLITE_OMIT_SHARED_CACHE 1 +#define SQLITE_DEFAULT_MEMSTATUS 0 +#define SQLITE_MAX_EXPR_DEPTH 0 +INCLUDE sqlite3.c +INCLUDE $ROOT/src/tclsqlite.c +INCLUDE $ROOT/ext/misc/btreeinfo.c +INCLUDE $ROOT/ext/repair/checkindex.c +INCLUDE $ROOT/ext/repair/checkfreelist.c + +/* +** Decode a pointer to an sqlite3 object. +*/ +int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ + struct SqliteDb *p; + Tcl_CmdInfo cmdInfo; + if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){ + p = (struct SqliteDb*)cmdInfo.objClientData; + *ppDb = p->db; + return TCL_OK; + }else{ + *ppDb = 0; + return TCL_ERROR; + } + return TCL_OK; +} + +/* +** sqlite3_imposter db main rootpage {CREATE TABLE...} ;# setup an imposter +** sqlite3_imposter db main ;# rm all imposters +*/ +static int sqlite3_imposter( + void *clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + const char *zSchema; + int iRoot; + const char *zSql; + + if( objc!=3 && objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB SCHEMA [ROOTPAGE SQL]"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + zSchema = Tcl_GetString(objv[2]); + if( objc==3 ){ + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 0, 1); + }else{ + if( Tcl_GetIntFromObj(interp, objv[3], &iRoot) ) return TCL_ERROR; + zSql = Tcl_GetString(objv[4]); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 1, iRoot); + sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 0, 0); + } + return TCL_OK; +} + +#include + +const char *sqlite3_checker_init_proc(Tcl_Interp *interp){ + Tcl_CreateObjCommand(interp, "sqlite3_imposter", + (Tcl_ObjCmdProc*)sqlite3_imposter, 0, 0); + sqlite3_auto_extension((void(*)(void))sqlite3_btreeinfo_init); + sqlite3_auto_extension((void(*)(void))sqlite3_checkindex_init); + sqlite3_auto_extension((void(*)(void))sqlite3_checkfreelist_init); + return +BEGIN_STRING +INCLUDE $ROOT/ext/repair/sqlite3_checker.tcl +END_STRING +; +} diff --git a/ext/repair/sqlite3_checker.tcl b/ext/repair/sqlite3_checker.tcl new file mode 100644 index 0000000000..2ae6e15b12 --- /dev/null +++ b/ext/repair/sqlite3_checker.tcl @@ -0,0 +1,264 @@ +# This TCL script is the main driver script for the sqlite3_checker utility +# program. +# + +# Special case: +# +# sqlite3_checker --test FILENAME ARGS +# +# uses FILENAME in place of this script. +# +if {[lindex $argv 0]=="--test" && [llength $argv]>1} { + set ::argv0 [lindex $argv 1] + set argv [lrange $argv 2 end] + source $argv0 + exit 0 +} + +# Emulate a TCL shell +# +proc tclsh {} { + set line {} + while {![eof stdin]} { + if {$line!=""} { + puts -nonewline "> " + } else { + puts -nonewline "% " + } + flush stdout + append line [gets stdin] + if {[info complete $line]} { + if {[catch {uplevel #0 $line} result]} { + puts stderr "Error: $result" + } elseif {$result!=""} { + puts $result + } + set line {} + } else { + append line \n + } + } +} + +# Do an incremental integrity check of a single index +# +proc check_index {idxname batchsize bTrace} { + set i 0 + set more 1 + set nerr 0 + set pct 00.0 + set max [db one {SELECT nEntry FROM sqlite_btreeinfo('main') + WHERE name=$idxname}] + puts -nonewline "$idxname: $i of $max rows ($pct%)\r" + flush stdout + if {$bTrace} { + set sql {SELECT errmsg, current_key AS key, + CASE WHEN rowid=1 THEN scanner_sql END AS traceOut + FROM incremental_index_check($idxname) + WHERE after_key=$key + LIMIT $batchsize} + } else { + set sql {SELECT errmsg, current_key AS key, NULL AS traceOut + FROM incremental_index_check($idxname) + WHERE after_key=$key + LIMIT $batchsize} + } + while {$more} { + set more 0 + db eval $sql { + set more 1 + if {$errmsg!=""} { + incr nerr + puts "$idxname: key($key): $errmsg" + } elseif {$traceOut!=""} { + puts "$idxname: $traceOut" + } + incr i + + } + set x [format {%.1f} [expr {($i*100.0)/$max}]] + if {$x!=$pct} { + puts -nonewline "$idxname: $i of $max rows ($pct%)\r" + flush stdout + set pct $x + } + } + puts "$idxname: $nerr errors out of $i entries" +} + +# Print a usage message on standard error, then quit. +# +proc usage {} { + set argv0 [file rootname [file tail [info nameofexecutable]]] + puts stderr "Usage: $argv0 OPTIONS database-filename" + puts stderr { +Do sanity checking on a live SQLite3 database file specified by the +"database-filename" argument. + +Options: + + --batchsize N Number of rows to check per transaction + + --freelist Perform a freelist check + + --index NAME Run a check of the index NAME + + --summary Print summary information about the database + + --table NAME Run a check of all indexes for table NAME + + --tclsh Run the built-in TCL interpreter (for debugging) + + --trace (Debugging only:) Output trace information on the scan + + --version Show the version number of SQLite +} + exit 1 +} + +set file_to_analyze {} +append argv {} +set bFreelistCheck 0 +set bSummary 0 +set zIndex {} +set zTable {} +set batchsize 1000 +set bAll 1 +set bTrace 0 +set argc [llength $argv] +for {set i 0} {$i<$argc} {incr i} { + set arg [lindex $argv $i] + if {[regexp {^-+tclsh$} $arg]} { + tclsh + exit 0 + } + if {[regexp {^-+version$} $arg]} { + sqlite3 mem :memory: + puts [mem one {SELECT sqlite_version()||' '||sqlite_source_id()}] + mem close + exit 0 + } + if {[regexp {^-+freelist$} $arg]} { + set bFreelistCheck 1 + set bAll 0 + continue + } + if {[regexp {^-+summary$} $arg]} { + set bSummary 1 + set bAll 0 + continue + } + if {[regexp {^-+trace$} $arg]} { + set bTrace 1 + continue + } + if {[regexp {^-+batchsize$} $arg]} { + incr i + if {$i>=$argc} { + puts stderr "missing argument on $arg" + exit 1 + } + set batchsize [lindex $argv $i] + continue + } + if {[regexp {^-+index$} $arg]} { + incr i + if {$i>=$argc} { + puts stderr "missing argument on $arg" + exit 1 + } + set zIndex [lindex $argv $i] + set bAll 0 + continue + } + if {[regexp {^-+table$} $arg]} { + incr i + if {$i>=$argc} { + puts stderr "missing argument on $arg" + exit 1 + } + set zTable [lindex $argv $i] + set bAll 0 + continue + } + if {[regexp {^-} $arg]} { + puts stderr "Unknown option: $arg" + usage + } + if {$file_to_analyze!=""} { + usage + } else { + set file_to_analyze $arg + } +} +if {$file_to_analyze==""} usage + +# If a TCL script is specified on the command-line, then run that +# script. +# +if {[file extension $file_to_analyze]==".tcl"} { + source $file_to_analyze + exit 0 +} + +set root_filename $file_to_analyze +regexp {^file:(//)?([^?]*)} $file_to_analyze all x1 root_filename +if {![file exists $root_filename]} { + puts stderr "No such file: $root_filename" + exit 1 +} +if {![file readable $root_filename]} { + puts stderr "File is not readable: $root_filename" + exit 1 +} + +if {[catch {sqlite3 db $file_to_analyze} res]} { + puts stderr "Cannot open datababase $root_filename: $res" + exit 1 +} + +if {$bFreelistCheck || $bAll} { + puts -nonewline "freelist-check: " + flush stdout + db eval BEGIN + puts [db one {SELECT checkfreelist('main')}] + db eval END +} +if {$bSummary} { + set scale 0 + set pgsz [db one {PRAGMA page_size}] + db eval {SELECT nPage*$pgsz AS sz, name, tbl_name + FROM sqlite_btreeinfo + WHERE type='index' + ORDER BY 1 DESC, name} { + if {$scale==0} { + if {$sz>10000000} { + set scale 1000000.0 + set unit MB + } else { + set scale 1000.0 + set unit KB + } + } + puts [format {%7.1f %s index %s of table %s} \ + [expr {$sz/$scale}] $unit $name $tbl_name] + } +} +if {$zIndex!=""} { + check_index $zIndex $batchsize $bTrace +} +if {$zTable!=""} { + foreach idx [db eval {SELECT name FROM sqlite_master + WHERE type='index' AND rootpage>0 + AND tbl_name=$zTable}] { + check_index $idx $batchsize $bTrace + } +} +if {$bAll} { + set allidx [db eval {SELECT name FROM sqlite_btreeinfo('main') + WHERE type='index' AND rootpage>0 + ORDER BY nEntry}] + foreach idx $allidx { + check_index $idx $batchsize $bTrace + } +} diff --git a/ext/repair/test/README.md b/ext/repair/test/README.md new file mode 100644 index 0000000000..8cc954adf5 --- /dev/null +++ b/ext/repair/test/README.md @@ -0,0 +1,13 @@ +To run these tests, first build sqlite3_checker: + + +> make sqlite3_checker + + +Then run the "test.tcl" script using: + + +> ./sqlite3_checker --test $path/test.tcl + + +Optionally add the full pathnames of individual *.test modules diff --git a/ext/repair/test/checkfreelist01.test b/ext/repair/test/checkfreelist01.test new file mode 100644 index 0000000000..7e2dd51c37 --- /dev/null +++ b/ext/repair/test/checkfreelist01.test @@ -0,0 +1,92 @@ +# 2017-10-11 + +set testprefix checkfreelist + +do_execsql_test 1.0 { + PRAGMA page_size=1024; + CREATE TABLE t1(a, b); +} + +do_execsql_test 1.2 { SELECT checkfreelist('main') } {ok} +do_execsql_test 1.3 { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000 + ) + INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s; + DELETE FROM t1 WHERE rowid%3; + PRAGMA freelist_count; +} {6726} + +do_execsql_test 1.4 { SELECT checkfreelist('main') } {ok} +do_execsql_test 1.5 { + WITH freelist_trunk(i, d, n) AS ( + SELECT 1, NULL, sqlite_readint32(data, 32) FROM sqlite_dbpage WHERE pgno=1 + UNION ALL + SELECT n, data, sqlite_readint32(data) + FROM freelist_trunk, sqlite_dbpage WHERE pgno=n + ) + SELECT i FROM freelist_trunk WHERE i!=1; +} { + 10009 9715 9343 8969 8595 8222 7847 7474 7102 6727 6354 5982 5608 5234 + 4860 4487 4112 3740 3367 2992 2619 2247 1872 1499 1125 752 377 5 +} + +do_execsql_test 1.6 { SELECT checkfreelist('main') } {ok} + +proc set_int {blob idx newval} { + binary scan $blob I* ints + lset ints $idx $newval + binary format I* $ints +} +db func set_int set_int + +proc get_int {blob idx} { + binary scan $blob I* ints + lindex $ints $idx +} +db func get_int get_int + +do_execsql_test 1.7 { + BEGIN; + UPDATE sqlite_dbpage + SET data = set_int(data, 1, get_int(data, 1)-1) + WHERE pgno=4860; + SELECT checkfreelist('main'); + ROLLBACK; +} {{free-list count mismatch: actual=6725 header=6726}} + +do_execsql_test 1.8 { + BEGIN; + UPDATE sqlite_dbpage + SET data = set_int(data, 5, (SELECT * FROM pragma_page_count)+1) + WHERE pgno=4860; + SELECT checkfreelist('main'); + ROLLBACK; +} {{leaf page 10092 is out of range (child 3 of trunk page 4860)}} + +do_execsql_test 1.9 { + BEGIN; + UPDATE sqlite_dbpage + SET data = set_int(data, 5, 0) + WHERE pgno=4860; + SELECT checkfreelist('main'); + ROLLBACK; +} {{leaf page 0 is out of range (child 3 of trunk page 4860)}} + +do_execsql_test 1.10 { + BEGIN; + UPDATE sqlite_dbpage + SET data = set_int(data, get_int(data, 1)+1, 0) + WHERE pgno=5; + SELECT checkfreelist('main'); + ROLLBACK; +} {{leaf page 0 is out of range (child 247 of trunk page 5)}} + +do_execsql_test 1.11 { + BEGIN; + UPDATE sqlite_dbpage + SET data = set_int(data, 1, 249) + WHERE pgno=5; + SELECT checkfreelist('main'); + ROLLBACK; +} {{leaf count out of range (249) on trunk page 5}} diff --git a/ext/repair/test/checkindex01.test b/ext/repair/test/checkindex01.test new file mode 100644 index 0000000000..25930397d3 --- /dev/null +++ b/ext/repair/test/checkindex01.test @@ -0,0 +1,351 @@ +# 2017-10-11 +# +set testprefix checkindex + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES('one', 2); + INSERT INTO t1 VALUES('two', 4); + INSERT INTO t1 VALUES('three', 6); + INSERT INTO t1 VALUES('four', 8); + INSERT INTO t1 VALUES('five', 10); + + CREATE INDEX i2 ON t1(a DESC); +} {} + +proc incr_index_check {idx nStep} { + set Q { + SELECT errmsg, current_key FROM incremental_index_check($idx, $after) + LIMIT $nStep + } + + set res [list] + while {1} { + unset -nocomplain current_key + set res1 [db eval $Q] + if {[llength $res1]==0} break + set res [concat $res $res1] + set after [lindex $res end] + } + + return $res +} + +proc do_index_check_test {tn idx res} { + uplevel [list do_execsql_test $tn.1 " + SELECT errmsg, current_key FROM incremental_index_check('$idx'); + " $res] + + uplevel [list do_test $tn.2 "incr_index_check $idx 1" [list {*}$res]] + uplevel [list do_test $tn.3 "incr_index_check $idx 2" [list {*}$res]] + uplevel [list do_test $tn.4 "incr_index_check $idx 5" [list {*}$res]] +} + + +do_execsql_test 1.2.1 { + SELECT rowid, errmsg IS NULL, current_key FROM incremental_index_check('i1'); +} { + 1 1 'five',5 + 2 1 'four',4 + 3 1 'one',1 + 4 1 'three',3 + 5 1 'two',2 +} +do_execsql_test 1.2.2 { + SELECT errmsg IS NULL, current_key, index_name, after_key, scanner_sql + FROM incremental_index_check('i1') LIMIT 1; +} { + 1 + 'five',5 + i1 + {} + {SELECT (SELECT a IS i.i0 FROM 't1' AS t WHERE "rowid" COLLATE BINARY IS i.i1), quote(i0)||','||quote(i1) FROM (SELECT (a) AS i0, ("rowid" COLLATE BINARY) AS i1 FROM 't1' INDEXED BY 'i1' ORDER BY 1,2) AS i} +} + +do_index_check_test 1.3 i1 { + {} 'five',5 + {} 'four',4 + {} 'one',1 + {} 'three',3 + {} 'two',2 +} + +do_index_check_test 1.4 i2 { + {} 'two',2 + {} 'three',3 + {} 'one',1 + {} 'four',4 + {} 'five',5 +} + +do_test 1.5 { + set tblroot [db one { SELECT rootpage FROM sqlite_master WHERE name='t1' }] + sqlite3_imposter db main $tblroot {CREATE TABLE xt1(a,b)} + db eval { + UPDATE xt1 SET a='six' WHERE rowid=3; + DELETE FROM xt1 WHERE rowid = 5; + } + sqlite3_imposter db main +} {} + +do_index_check_test 1.6 i1 { + {row missing} 'five',5 + {} 'four',4 + {} 'one',1 + {row data mismatch} 'three',3 + {} 'two',2 +} + +do_index_check_test 1.7 i2 { + {} 'two',2 + {row data mismatch} 'three',3 + {} 'one',1 + {} 'four',4 + {row missing} 'five',5 +} + +#-------------------------------------------------------------------------- +do_execsql_test 2.0 { + + CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c, d); + + INSERT INTO t2 VALUES(1, NULL, 1, 1); + INSERT INTO t2 VALUES(2, 1, NULL, 1); + INSERT INTO t2 VALUES(3, 1, 1, NULL); + + INSERT INTO t2 VALUES(4, 2, 2, 1); + INSERT INTO t2 VALUES(5, 2, 2, 2); + INSERT INTO t2 VALUES(6, 2, 2, 3); + + INSERT INTO t2 VALUES(7, 2, 2, 1); + INSERT INTO t2 VALUES(8, 2, 2, 2); + INSERT INTO t2 VALUES(9, 2, 2, 3); + + CREATE INDEX i3 ON t2(b, c, d); + CREATE INDEX i4 ON t2(b DESC, c DESC, d DESC); + CREATE INDEX i5 ON t2(d, c DESC, b); +} {} + +do_index_check_test 2.1 i3 { + {} NULL,1,1,1 + {} 1,NULL,1,2 + {} 1,1,NULL,3 + {} 2,2,1,4 + {} 2,2,1,7 + {} 2,2,2,5 + {} 2,2,2,8 + {} 2,2,3,6 + {} 2,2,3,9 +} + +do_index_check_test 2.2 i4 { + {} 2,2,3,6 + {} 2,2,3,9 + {} 2,2,2,5 + {} 2,2,2,8 + {} 2,2,1,4 + {} 2,2,1,7 + {} 1,1,NULL,3 + {} 1,NULL,1,2 + {} NULL,1,1,1 +} + +do_index_check_test 2.3 i5 { + {} NULL,1,1,3 + {} 1,2,2,4 + {} 1,2,2,7 + {} 1,1,NULL,1 + {} 1,NULL,1,2 + {} 2,2,2,5 + {} 2,2,2,8 + {} 3,2,2,6 + {} 3,2,2,9 +} + +#-------------------------------------------------------------------------- +do_execsql_test 3.0 { + + CREATE TABLE t3(w, x, y, z PRIMARY KEY) WITHOUT ROWID; + CREATE INDEX t3wxy ON t3(w, x, y); + CREATE INDEX t3wxy2 ON t3(w DESC, x DESC, y DESC); + + INSERT INTO t3 VALUES(NULL, NULL, NULL, 1); + INSERT INTO t3 VALUES(NULL, NULL, NULL, 2); + INSERT INTO t3 VALUES(NULL, NULL, NULL, 3); + + INSERT INTO t3 VALUES('a', NULL, NULL, 4); + INSERT INTO t3 VALUES('a', NULL, NULL, 5); + INSERT INTO t3 VALUES('a', NULL, NULL, 6); + + INSERT INTO t3 VALUES('a', 'b', NULL, 7); + INSERT INTO t3 VALUES('a', 'b', NULL, 8); + INSERT INTO t3 VALUES('a', 'b', NULL, 9); + +} {} + +do_index_check_test 3.1 t3wxy { + {} NULL,NULL,NULL,1 {} NULL,NULL,NULL,2 {} NULL,NULL,NULL,3 + {} 'a',NULL,NULL,4 {} 'a',NULL,NULL,5 {} 'a',NULL,NULL,6 + {} 'a','b',NULL,7 {} 'a','b',NULL,8 {} 'a','b',NULL,9 +} +do_index_check_test 3.2 t3wxy2 { + {} 'a','b',NULL,7 {} 'a','b',NULL,8 {} 'a','b',NULL,9 + {} 'a',NULL,NULL,4 {} 'a',NULL,NULL,5 {} 'a',NULL,NULL,6 + {} NULL,NULL,NULL,1 {} NULL,NULL,NULL,2 {} NULL,NULL,NULL,3 +} + +#-------------------------------------------------------------------------- +# Test with an index that uses non-default collation sequences. +# +do_execsql_test 4.0 { + CREATE TABLE t4(a INTEGER PRIMARY KEY, c1 TEXT, c2 TEXT); + INSERT INTO t4 VALUES(1, 'aaa', 'bbb'); + INSERT INTO t4 VALUES(2, 'AAA', 'CCC'); + INSERT INTO t4 VALUES(3, 'aab', 'ddd'); + INSERT INTO t4 VALUES(4, 'AAB', 'EEE'); + + CREATE INDEX t4cc ON t4(c1 COLLATE nocase, c2 COLLATE nocase); +} + +do_index_check_test 4.1 t4cc { + {} 'aaa','bbb',1 + {} 'AAA','CCC',2 + {} 'aab','ddd',3 + {} 'AAB','EEE',4 +} + +do_test 4.2 { + set tblroot [db one { SELECT rootpage FROM sqlite_master WHERE name='t4' }] + sqlite3_imposter db main $tblroot \ + {CREATE TABLE xt4(a INTEGER PRIMARY KEY, c1 TEXT, c2 TEXT)} + + db eval { + UPDATE xt4 SET c1='hello' WHERE rowid=2; + DELETE FROM xt4 WHERE rowid = 3; + } + sqlite3_imposter db main +} {} + +do_index_check_test 4.3 t4cc { + {} 'aaa','bbb',1 + {row data mismatch} 'AAA','CCC',2 + {row missing} 'aab','ddd',3 + {} 'AAB','EEE',4 +} + +#-------------------------------------------------------------------------- +# Test an index on an expression. +# +do_execsql_test 5.0 { + CREATE TABLE t5(x INTEGER PRIMARY KEY, y TEXT, UNIQUE(y)); + INSERT INTO t5 VALUES(1, '{"x":1, "y":1}'); + INSERT INTO t5 VALUES(2, '{"x":2, "y":2}'); + INSERT INTO t5 VALUES(3, '{"x":3, "y":3}'); + INSERT INTO t5 VALUES(4, '{"w":4, "z":4}'); + INSERT INTO t5 VALUES(5, '{"x":5, "y":5}'); + + CREATE INDEX t5x ON t5( json_extract(y, '$.x') ); + CREATE INDEX t5y ON t5( json_extract(y, '$.y') DESC ); +} + +do_index_check_test 5.1.1 t5x { + {} NULL,4 {} 1,1 {} 2,2 {} 3,3 {} 5,5 +} + +do_index_check_test 5.1.2 t5y { + {} 5,5 {} 3,3 {} 2,2 {} 1,1 {} NULL,4 +} + +do_index_check_test 5.1.3 sqlite_autoindex_t5_1 { + {} {'{"w":4, "z":4}',4} + {} {'{"x":1, "y":1}',1} + {} {'{"x":2, "y":2}',2} + {} {'{"x":3, "y":3}',3} + {} {'{"x":5, "y":5}',5} +} + +do_test 5.2 { + set tblroot [db one { SELECT rootpage FROM sqlite_master WHERE name='t5' }] + sqlite3_imposter db main $tblroot \ + {CREATE TABLE xt5(a INTEGER PRIMARY KEY, c1 TEXT);} + db eval { + UPDATE xt5 SET c1='{"x":22, "y":11}' WHERE rowid=1; + DELETE FROM xt5 WHERE rowid = 4; + } + sqlite3_imposter db main +} {} + +do_index_check_test 5.3.1 t5x { + {row missing} NULL,4 + {row data mismatch} 1,1 + {} 2,2 + {} 3,3 + {} 5,5 +} + +do_index_check_test 5.3.2 sqlite_autoindex_t5_1 { + {row missing} {'{"w":4, "z":4}',4} + {row data mismatch} {'{"x":1, "y":1}',1} + {} {'{"x":2, "y":2}',2} + {} {'{"x":3, "y":3}',3} + {} {'{"x":5, "y":5}',5} +} + +#------------------------------------------------------------------------- +# +do_execsql_test 6.0 { + CREATE TABLE t6(x INTEGER PRIMARY KEY, y, z); + CREATE INDEX t6x1 ON t6(y, /* one,two,three */ z); + CREATE INDEX t6x2 ON t6(z, -- hello,world, + y); + + CREATE INDEX t6x3 ON t6(z -- hello,world + , y); + + INSERT INTO t6 VALUES(1, 2, 3); + INSERT INTO t6 VALUES(4, 5, 6); +} + +do_index_check_test 6.1 t6x1 { + {} 2,3,1 + {} 5,6,4 +} +do_index_check_test 6.2 t6x2 { + {} 3,2,1 + {} 6,5,4 +} +do_index_check_test 6.2 t6x3 { + {} 3,2,1 + {} 6,5,4 +} + +#------------------------------------------------------------------------- +# +do_execsql_test 7.0 { + CREATE TABLE t7(x INTEGER PRIMARY KEY, y, z); + INSERT INTO t7 VALUES(1, 1, 1); + INSERT INTO t7 VALUES(2, 2, 0); + INSERT INTO t7 VALUES(3, 3, 1); + INSERT INTO t7 VALUES(4, 4, 0); + + CREATE INDEX t7i1 ON t7(y) WHERE z=1; + CREATE INDEX t7i2 ON t7(y) /* hello,world */ WHERE z=1; + CREATE INDEX t7i3 ON t7(y) WHERE -- yep + z=1; + CREATE INDEX t7i4 ON t7(y) WHERE z=1 -- yep; +} +do_index_check_test 7.1 t7i1 { + {} 1,1 {} 3,3 +} +do_index_check_test 7.2 t7i2 { + {} 1,1 {} 3,3 +} +do_index_check_test 7.3 t7i3 { + {} 1,1 {} 3,3 +} +do_index_check_test 7.4 t7i4 { + {} 1,1 {} 3,3 +} + + diff --git a/ext/repair/test/test.tcl b/ext/repair/test/test.tcl new file mode 100644 index 0000000000..c073bb73c5 --- /dev/null +++ b/ext/repair/test/test.tcl @@ -0,0 +1,67 @@ +# Run this script using +# +# sqlite3_checker --test $thisscript $testscripts +# +# The $testscripts argument is optional. If omitted, all *.test files +# in the same directory as $thisscript are run. +# +set NTEST 0 +set NERR 0 + + +# Invoke the do_test procedure to run a single test +# +# The $expected parameter is the expected result. The result is the return +# value from the last TCL command in $cmd. +# +# Normally, $expected must match exactly. But if $expected is of the form +# "/regexp/" then regular expression matching is used. If $expected is +# "~/regexp/" then the regular expression must NOT match. If $expected is +# of the form "#/value-list/" then each term in value-list must be numeric +# and must approximately match the corresponding numeric term in $result. +# Values must match within 10%. Or if the $expected term is A..B then the +# $result term must be in between A and B. +# +proc do_test {name cmd expected} { + if {[info exists ::testprefix]} { + set name "$::testprefix$name" + } + + incr ::NTEST + puts -nonewline $name... + flush stdout + + if {[catch {uplevel #0 "$cmd;\n"} result]} { + puts -nonewline $name... + puts "\nError: $result" + incr ::NERR + } else { + set ok [expr {[string compare $result $expected]==0}] + if {!$ok} { + puts "\n! $name expected: \[$expected\]\n! $name got: \[$result\]" + incr ::NERR + } else { + puts " Ok" + } + } + flush stdout +} + +# +# do_execsql_test TESTNAME SQL RES +# +proc do_execsql_test {testname sql {result {}}} { + uplevel [list do_test $testname [list db eval $sql] [list {*}$result]] +} + +if {[llength $argv]==0} { + set dir [file dirname $argv0] + set argv [glob -nocomplain $dir/*.test] +} +foreach testfile $argv { + file delete -force test.db + sqlite3 db test.db + source $testfile + catch {db close} +} +puts "$NERR errors out of $NTEST tests" diff --git a/ext/rtree/geopoly.c b/ext/rtree/geopoly.c new file mode 100644 index 0000000000..c3f3478b5c --- /dev/null +++ b/ext/rtree/geopoly.c @@ -0,0 +1,1778 @@ +/* +** 2018-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 file implements an alternative R-Tree virtual table that +** uses polygons to express the boundaries of 2-dimensional objects. +** +** This file is #include-ed onto the end of "rtree.c" so that it has +** access to all of the R-Tree internals. +*/ +#include + +/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */ +#ifdef GEOPOLY_ENABLE_DEBUG + static int geo_debug = 0; +# define GEODEBUG(X) if(geo_debug)printf X +#else +# define GEODEBUG(X) +#endif + +#ifndef JSON_NULL /* The following stuff repeats things found in json1 */ +/* +** Versions of isspace(), isalnum() and isdigit() to which it is safe +** to pass signed char values. +*/ +#ifdef sqlite3Isdigit + /* Use the SQLite core versions if this routine is part of the + ** SQLite amalgamation */ +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) +#else + /* Use the standard library for separate compilation */ +#include /* amalgamator: keep */ +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) +#endif + +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function. +*/ +static const char geopolyIsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x]) +#endif /* JSON NULL - back to original code */ + +/* Compiler and version */ +#ifndef GCC_VERSION +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#endif +#ifndef MSVC_VERSION +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif +#endif + +/* Datatype for coordinates +*/ +typedef float GeoCoord; + +/* +** Internal representation of a polygon. +** +** The polygon consists of a sequence of vertexes. There is a line +** segment between each pair of vertexes, and one final segment from +** the last vertex back to the first. (This differs from the GeoJSON +** standard in which the final vertex is a repeat of the first.) +** +** The polygon follows the right-hand rule. The area to the right of +** each segment is "outside" and the area to the left is "inside". +** +** The on-disk representation consists of a 4-byte header followed by +** the values. The 4-byte header is: +** +** encoding (1 byte) 0=big-endian, 1=little-endian +** nvertex (3 bytes) Number of vertexes as a big-endian integer +** +** Enough space is allocated for 4 coordinates, to work around over-zealous +** warnings coming from some compiler (notably, clang). In reality, the size +** of each GeoPoly memory allocate is adjusted as necessary so that the +** GeoPoly.a[] array at the end is the appropriate size. +*/ +typedef struct GeoPoly GeoPoly; +struct GeoPoly { + int nVertex; /* Number of vertexes */ + unsigned char hdr[4]; /* Header for on-disk representation */ + GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */ +}; + +/* The size of a memory allocation needed for a GeoPoly object sufficient +** to hold N coordinate pairs. +*/ +#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4)) + +/* +** State of a parse of a GeoJSON input. +*/ +typedef struct GeoParse GeoParse; +struct GeoParse { + const unsigned char *z; /* Unparsed input */ + int nVertex; /* Number of vertexes in a[] */ + int nAlloc; /* Space allocated to a[] */ + int nErr; /* Number of errors encountered */ + GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */ +}; + +/* Do a 4-byte byte swap */ +static void geopolySwab32(unsigned char *a){ + unsigned char t = a[0]; + a[0] = a[3]; + a[3] = t; + t = a[1]; + a[1] = a[2]; + a[2] = t; +} + +/* Skip whitespace. Return the next non-whitespace character. */ +static char geopolySkipSpace(GeoParse *p){ + while( safe_isspace(p->z[0]) ) p->z++; + return p->z[0]; +} + +/* Parse out a number. Write the value into *pVal if pVal!=0. +** return non-zero on success and zero if the next token is not a number. +*/ +static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ + char c = geopolySkipSpace(p); + const unsigned char *z = p->z; + int j = 0; + int seenDP = 0; + int seenE = 0; + if( c=='-' ){ + j = 1; + c = z[j]; + } + if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0; + for(;; j++){ + c = z[j]; + if( safe_isdigit(c) ) continue; + if( c=='.' ){ + if( z[j-1]=='-' ) return 0; + if( seenDP ) return 0; + seenDP = 1; + continue; + } + if( c=='e' || c=='E' ){ + if( z[j-1]<'0' ) return 0; + if( seenE ) return -1; + seenDP = seenE = 1; + c = z[j+1]; + if( c=='+' || c=='-' ){ + j++; + c = z[j+1]; + } + if( c<'0' || c>'9' ) return 0; + continue; + } + break; + } + if( z[j-1]<'0' ) return 0; + if( pVal ){ +#ifdef SQLITE_AMALGAMATION + /* The sqlite3AtoF() routine is much much faster than atof(), if it + ** is available */ + double r; + (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8); + *pVal = r; +#else + *pVal = (GeoCoord)atof((const char*)p->z); +#endif + } + p->z += j; + return 1; +} + +/* +** If the input is a well-formed JSON array of coordinates with at least +** four coordinates and where each coordinate is itself a two-value array, +** then convert the JSON into a GeoPoly object and return a pointer to +** that object. +** +** If any error occurs, return NULL. +*/ +static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ + GeoParse s; + int rc = SQLITE_OK; + memset(&s, 0, sizeof(s)); + s.z = z; + if( geopolySkipSpace(&s)=='[' ){ + s.z++; + while( geopolySkipSpace(&s)=='[' ){ + int ii = 0; + char c; + s.z++; + if( s.nVertex>=s.nAlloc ){ + GeoCoord *aNew; + s.nAlloc = s.nAlloc*2 + 16; + aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); + if( aNew==0 ){ + rc = SQLITE_NOMEM; + s.nErr++; + break; + } + s.a = aNew; + } + while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ + ii++; + if( ii==2 ) s.nVertex++; + c = geopolySkipSpace(&s); + s.z++; + if( c==',' ) continue; + if( c==']' && ii>=2 ) break; + s.nErr++; + rc = SQLITE_ERROR; + goto parse_json_err; + } + if( geopolySkipSpace(&s)==',' ){ + s.z++; + continue; + } + break; + } + if( geopolySkipSpace(&s)==']' + && s.nVertex>=4 + && s.a[0]==s.a[s.nVertex*2-2] + && s.a[1]==s.a[s.nVertex*2-1] + && (s.z++, geopolySkipSpace(&s)==0) + ){ + GeoPoly *pOut; + int x = 1; + s.nVertex--; /* Remove the redundant vertex at the end */ + pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) ); + x = 1; + if( pOut==0 ) goto parse_json_err; + pOut->nVertex = s.nVertex; + memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord)); + pOut->hdr[0] = *(unsigned char*)&x; + pOut->hdr[1] = (s.nVertex>>16)&0xff; + pOut->hdr[2] = (s.nVertex>>8)&0xff; + pOut->hdr[3] = s.nVertex&0xff; + sqlite3_free(s.a); + if( pRc ) *pRc = SQLITE_OK; + return pOut; + }else{ + s.nErr++; + rc = SQLITE_ERROR; + } + } +parse_json_err: + if( pRc ) *pRc = rc; + sqlite3_free(s.a); + return 0; +} + +/* +** Given a function parameter, try to interpret it as a polygon, either +** in the binary format or JSON text. Compute a GeoPoly object and +** return a pointer to that object. Or if the input is not a well-formed +** polygon, put an error message in sqlite3_context and return NULL. +*/ +static GeoPoly *geopolyFuncParam( + sqlite3_context *pCtx, /* Context for error messages */ + sqlite3_value *pVal, /* The value to decode */ + int *pRc /* Write error here */ +){ + GeoPoly *p = 0; + int nByte; + if( sqlite3_value_type(pVal)==SQLITE_BLOB + && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) + ){ + const unsigned char *a = sqlite3_value_blob(pVal); + int nVertex; + nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; + if( (a[0]==0 || a[0]==1) + && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte + ){ + p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + if( pCtx ) sqlite3_result_error_nomem(pCtx); + }else{ + int x = 1; + p->nVertex = nVertex; + memcpy(p->hdr, a, nByte); + if( a[0] != *(unsigned char*)&x ){ + int ii; + for(ii=0; iia[ii]); + } + p->hdr[0] ^= 1; + } + } + } + if( pRc ) *pRc = SQLITE_OK; + return p; + }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ + const unsigned char *zJson = sqlite3_value_text(pVal); + if( zJson==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + return geopolyParseJson(zJson, pRc); + }else{ + if( pRc ) *pRc = SQLITE_ERROR; + return 0; + } +} + +/* +** Implementation of the geopoly_blob(X) function. +** +** If the input is a well-formed Geopoly BLOB or JSON string +** then return the BLOB representation of the polygon. Otherwise +** return NULL. +*/ +static void geopolyBlobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_json(X) +** +** Interpret X as a polygon and render it as a JSON array +** of coordinates. Or, if X is not a valid polygon, return NULL. +*/ +static void geopolyJsonFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + sqlite3_str_append(x, "[", 1); + for(i=0; inVertex; i++){ + sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]); + } + sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_svg(X, ....) +** +** Interpret X as a polygon and render it as a SVG . +** Additional arguments are added as attributes to the . +*/ +static void geopolySvgFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + char cSep = '\''; + sqlite3_str_appendf(x, "a[i*2], p->a[i*2+1]); + cSep = ' '; + } + sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]); + for(i=1; i"); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL Function: geopoly_xform(poly, A, B, C, D, E, F) +** +** Transform and/or translate a polygon as follows: +** +** x1 = A*x0 + B*y0 + E +** y1 = C*x0 + D*y0 + F +** +** For a translation: +** +** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset) +** +** Rotate by R around the point (0,0): +** +** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0) +*/ +static void geopolyXformFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + double A = sqlite3_value_double(argv[1]); + double B = sqlite3_value_double(argv[2]); + double C = sqlite3_value_double(argv[3]); + double D = sqlite3_value_double(argv[4]); + double E = sqlite3_value_double(argv[5]); + double F = sqlite3_value_double(argv[6]); + GeoCoord x1, y1, x0, y0; + int ii; + if( p ){ + for(ii=0; iinVertex; ii++){ + x0 = p->a[ii*2]; + y0 = p->a[ii*2+1]; + x1 = (GeoCoord)(A*x0 + B*y0 + E); + y1 = (GeoCoord)(C*x0 + D*y0 + F); + p->a[ii*2] = x1; + p->a[ii*2+1] = y1; + } + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** Implementation of the geopoly_area(X) function. +** +** If the input is a well-formed Geopoly BLOB then return the area +** enclosed by the polygon. If the polygon circulates clockwise instead +** of counterclockwise (as it should) then return the negative of the +** enclosed area. Otherwise return NULL. +*/ +static void geopolyAreaFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + double rArea = 0.0; + int ii; + for(ii=0; iinVertex-1; ii++){ + rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ + * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ + * 0.5; + } + rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ + * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ + * 0.5; + sqlite3_result_double(context, rArea); + sqlite3_free(p); + } +} + +/* +** Implementation of the geopoly_reverse(X) function. +** +** Reverse the order of the vertexes in polygon X. This can be used +** to convert an historical polygon that uses a clockwise rotation into +** a well-formed GeoJSON polygon that uses counter-clockwise rotation. +*/ +static void geopolyReverseFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + int ii, jj; + for(ii=2, jj=p->nVertex*2 - 4; iia[ii]; + p->a[ii] = p->a[jj]; + p->a[jj] = t; + t = p->a[ii+1]; + p->a[ii+1] = p->a[jj+1]; + p->a[jj+1] = t; + + } + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +#define GEOPOLY_PI 3.1415926535897932385 + +/* Fast approximation for cosine(X) for X between -0.5*pi and 2*pi +*/ +static double geopolyCosine(double r){ + assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI ); + if( r>=1.5*GEOPOLY_PI ){ + r -= 2.0*GEOPOLY_PI; + } + if( r>=0.5*GEOPOLY_PI ){ + return -geopolyCosine(r-GEOPOLY_PI); + }else{ + double r2 = r*r; + double r3 = r2*r; + double r5 = r3*r2; + return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5; + } +} + +/* +** Function: geopoly_regular(X,Y,R,N) +** +** Construct a simple, convex, regular polygon centered at X, Y +** with circumradius R and with N sides. +*/ +static void geopolyRegularFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x = sqlite3_value_double(argv[0]); + double y = sqlite3_value_double(argv[1]); + double r = sqlite3_value_double(argv[2]); + int n = sqlite3_value_int(argv[3]); + int i; + GeoPoly *p; + + if( n<3 || r<=0.0 ) return; + if( n>1000 ) n = 1000; + p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + i = 1; + p->hdr[0] = *(unsigned char*)&i; + p->hdr[1] = 0; + p->hdr[2] = (n>>8)&0xff; + p->hdr[3] = n&0xff; + for(i=0; ia[i*2] = x - r*geopolyCosine(rAngle-0.5*GEOPOLY_PI); + p->a[i*2+1] = y + r*geopolyCosine(rAngle); + } + sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT); + sqlite3_free(p); +} + +/* +** If pPoly is a polygon, compute its bounding box. Then: +** +** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL +** (2) otherwise, compute a GeoPoly for the bounding box and return the +** new GeoPoly +** +** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from +** the bounding box in aCoord and return a pointer to that GeoPoly. +*/ +static GeoPoly *geopolyBBox( + sqlite3_context *context, /* For recording the error */ + sqlite3_value *pPoly, /* The polygon */ + RtreeCoord *aCoord, /* Results here */ + int *pRc /* Error code here */ +){ + GeoPoly *pOut = 0; + GeoPoly *p; + float mnX, mxX, mnY, mxY; + if( pPoly==0 && aCoord!=0 ){ + p = 0; + mnX = aCoord[0].f; + mxX = aCoord[1].f; + mnY = aCoord[2].f; + mxY = aCoord[3].f; + goto geopolyBboxFill; + }else{ + p = geopolyFuncParam(context, pPoly, pRc); + } + if( p ){ + int ii; + mnX = mxX = p->a[0]; + mnY = mxY = p->a[1]; + for(ii=1; iinVertex; ii++){ + double r = p->a[ii*2]; + if( rmxX ) mxX = (float)r; + r = p->a[ii*2+1]; + if( rmxY ) mxY = (float)r; + } + if( pRc ) *pRc = SQLITE_OK; + if( aCoord==0 ){ + geopolyBboxFill: + pOut = sqlite3_realloc(p, GEOPOLY_SZ(4)); + if( pOut==0 ){ + sqlite3_free(p); + if( context ) sqlite3_result_error_nomem(context); + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + pOut->nVertex = 4; + ii = 1; + pOut->hdr[0] = *(unsigned char*)ⅈ + pOut->hdr[1] = 0; + pOut->hdr[2] = 0; + pOut->hdr[3] = 4; + pOut->a[0] = mnX; + pOut->a[1] = mnY; + pOut->a[2] = mxX; + pOut->a[3] = mnY; + pOut->a[4] = mxX; + pOut->a[5] = mxY; + pOut->a[6] = mnX; + pOut->a[7] = mxY; + }else{ + sqlite3_free(p); + aCoord[0].f = mnX; + aCoord[1].f = mxX; + aCoord[2].f = mnY; + aCoord[3].f = mxY; + } + } + return pOut; +} + +/* +** Implementation of the geopoly_bbox(X) SQL function. +*/ +static void geopolyBBoxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** State vector for the geopoly_group_bbox() aggregate function. +*/ +typedef struct GeoBBox GeoBBox; +struct GeoBBox { + int isInit; + RtreeCoord a[4]; +}; + + +/* +** Implementation of the geopoly_group_bbox(X) aggregate SQL function. +*/ +static void geopolyBBoxStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + RtreeCoord a[4]; + int rc = SQLITE_OK; + (void)geopolyBBox(context, argv[0], a, &rc); + if( rc==SQLITE_OK ){ + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); + if( pBBox==0 ) return; + if( pBBox->isInit==0 ){ + pBBox->isInit = 1; + memcpy(pBBox->a, a, sizeof(RtreeCoord)*4); + }else{ + if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0]; + if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1]; + if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2]; + if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3]; + } + } +} +static void geopolyBBoxFinal( + sqlite3_context *context +){ + GeoPoly *p; + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0); + if( pBBox==0 ) return; + p = geopolyBBox(context, 0, pBBox->a, 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + + +/* +** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). +** Returns: +** +** +2 x0,y0 is on the line segement +** +** +1 x0,y0 is beneath line segment +** +** 0 x0,y0 is not on or beneath the line segment or the line segment +** is vertical and x0,y0 is not on the line segment +** +** The left-most coordinate min(x1,x2) is not considered to be part of +** the line segment for the purposes of this analysis. +*/ +static int pointBeneathLine( + double x0, double y0, + double x1, double y1, + double x2, double y2 +){ + double y; + if( x0==x1 && y0==y1 ) return 2; + if( x1x2 ) return 0; + }else if( x1>x2 ){ + if( x0<=x2 || x0>x1 ) return 0; + }else{ + /* Vertical line segment */ + if( x0!=x1 ) return 0; + if( y0y1 && y0>y2 ) return 0; + return 2; + } + y = y1 + (y2-y1)*(x0-x1)/(x2-x1); + if( y0==y ) return 2; + if( y0nVertex-1; ii++){ + v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], + p1->a[ii*2+2],p1->a[ii*2+3]); + if( v==2 ) break; + cnt += v; + } + if( v!=2 ){ + v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], + p1->a[0],p1->a[1]); + } + if( v==2 ){ + sqlite3_result_int(context, 1); + }else if( ((v+cnt)&1)==0 ){ + sqlite3_result_int(context, 0); + }else{ + sqlite3_result_int(context, 2); + } + sqlite3_free(p1); +} + +/* Forward declaration */ +static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2); + +/* +** SQL function: geopoly_within(P1,P2) +** +** Return +2 if P1 and P2 are the same polygon +** Return +1 if P2 is contained within P1 +** Return 0 if any part of P2 is on the outside of P1 +** +*/ +static void geopolyWithinFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* Objects used by the overlap algorihm. */ +typedef struct GeoEvent GeoEvent; +typedef struct GeoSegment GeoSegment; +typedef struct GeoOverlap GeoOverlap; +struct GeoEvent { + double x; /* X coordinate at which event occurs */ + int eType; /* 0 for ADD, 1 for REMOVE */ + GeoSegment *pSeg; /* The segment to be added or removed */ + GeoEvent *pNext; /* Next event in the sorted list */ +}; +struct GeoSegment { + double C, B; /* y = C*x + B */ + double y; /* Current y value */ + float y0; /* Initial y value */ + unsigned char side; /* 1 for p1, 2 for p2 */ + unsigned int idx; /* Which segment within the side */ + GeoSegment *pNext; /* Next segment in a list sorted by y */ +}; +struct GeoOverlap { + GeoEvent *aEvent; /* Array of all events */ + GeoSegment *aSegment; /* Array of all segments */ + int nEvent; /* Number of events */ + int nSegment; /* Number of segments */ +}; + +/* +** Add a single segment and its associated events. +*/ +static void geopolyAddOneSegment( + GeoOverlap *p, + GeoCoord x0, + GeoCoord y0, + GeoCoord x1, + GeoCoord y1, + unsigned char side, + unsigned int idx +){ + GeoSegment *pSeg; + GeoEvent *pEvent; + if( x0==x1 ) return; /* Ignore vertical segments */ + if( x0>x1 ){ + GeoCoord t = x0; + x0 = x1; + x1 = t; + t = y0; + y0 = y1; + y1 = t; + } + pSeg = p->aSegment + p->nSegment; + p->nSegment++; + pSeg->C = (y1-y0)/(x1-x0); + pSeg->B = y1 - x1*pSeg->C; + pSeg->y0 = y0; + pSeg->side = side; + pSeg->idx = idx; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x0; + pEvent->eType = 0; + pEvent->pSeg = pSeg; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x1; + pEvent->eType = 1; + pEvent->pSeg = pSeg; +} + + + +/* +** Insert all segments and events for polygon pPoly. +*/ +static void geopolyAddSegments( + GeoOverlap *p, /* Add segments to this Overlap object */ + GeoPoly *pPoly, /* Take all segments from this polygon */ + unsigned char side /* The side of pPoly */ +){ + unsigned int i; + GeoCoord *x; + for(i=0; i<(unsigned)pPoly->nVertex-1; i++){ + x = pPoly->a + (i*2); + geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i); + } + x = pPoly->a + (i*2); + geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i); +} + +/* +** Merge two lists of sorted events by X coordinate +*/ +static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){ + GeoEvent head, *pLast; + head.pNext = 0; + pLast = &head; + while( pRight && pLeft ){ + if( pRight->x <= pLeft->x ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort an array of nEvent event objects into a list. +*/ +static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){ + int mx = 0; + int i, j; + GeoEvent *p; + GeoEvent *a[50]; + for(i=0; ipNext = 0; + for(j=0; j=mx ) mx = j+1; + } + p = 0; + for(i=0; iy - pLeft->y; + if( r==0.0 ) r = pRight->C - pLeft->C; + if( r<0.0 ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort a list of GeoSegments in order of increasing Y and in the event of +** a tie, increasing C (slope). +*/ +static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){ + int mx = 0; + int i; + GeoSegment *p; + GeoSegment *a[50]; + while( pList ){ + p = pList; + pList = pList->pNext; + p->pNext = 0; + for(i=0; i=mx ) mx = i+1; + } + p = 0; + for(i=0; inVertex + p2->nVertex + 2; + GeoOverlap *p; + int nByte; + GeoEvent *pThisEvent; + double rX; + int rc = 0; + int needSort = 0; + GeoSegment *pActive = 0; + GeoSegment *pSeg; + unsigned char aOverlap[4]; + + nByte = sizeof(GeoEvent)*nVertex*2 + + sizeof(GeoSegment)*nVertex + + sizeof(GeoOverlap); + p = sqlite3_malloc( nByte ); + if( p==0 ) return -1; + p->aEvent = (GeoEvent*)&p[1]; + p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2]; + p->nEvent = p->nSegment = 0; + geopolyAddSegments(p, p1, 1); + geopolyAddSegments(p, p2, 2); + pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); + rX = pThisEvent->x==0.0 ? -1.0 : 0.0; + memset(aOverlap, 0, sizeof(aOverlap)); + while( pThisEvent ){ + if( pThisEvent->x!=rX ){ + GeoSegment *pPrev = 0; + int iMask = 0; + GEODEBUG(("Distinct X: %g\n", pThisEvent->x)); + rX = pThisEvent->x; + if( needSort ){ + GEODEBUG(("SORT\n")); + pActive = geopolySortSegmentsByYAndC(pActive); + needSort = 0; + } + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pPrev ){ + if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + pPrev = 0; + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + double y = pSeg->C*rX + pSeg->B; + GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y)); + pSeg->y = y; + if( pPrev ){ + if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){ + rc = 1; + GEODEBUG(("Crossing: %d.%d and %d.%d\n", + pPrev->side, pPrev->idx, + pSeg->side, pSeg->idx)); + goto geopolyOverlapDone; + }else if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + } + GEODEBUG(("%s %d.%d C=%g B=%g\n", + pThisEvent->eType ? "RM " : "ADD", + pThisEvent->pSeg->side, pThisEvent->pSeg->idx, + pThisEvent->pSeg->C, + pThisEvent->pSeg->B)); + if( pThisEvent->eType==0 ){ + /* Add a segment */ + pSeg = pThisEvent->pSeg; + pSeg->y = pSeg->y0; + pSeg->pNext = pActive; + pActive = pSeg; + needSort = 1; + }else{ + /* Remove a segment */ + if( pActive==pThisEvent->pSeg ){ + pActive = pActive->pNext; + }else{ + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pSeg->pNext==pThisEvent->pSeg ){ + pSeg->pNext = pSeg->pNext->pNext; + break; + } + } + } + } + pThisEvent = pThisEvent->pNext; + } + if( aOverlap[3]==0 ){ + rc = 0; + }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){ + rc = 3; + }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){ + rc = 2; + }else if( aOverlap[1]==0 && aOverlap[2]==0 ){ + rc = 4; + }else{ + rc = 1; + } + +geopolyOverlapDone: + sqlite3_free(p); + return rc; +} + +/* +** SQL function: geopoly_overlap(P1,P2) +** +** Determine whether or not P1 and P2 overlap. Return value: +** +** 0 The two polygons are disjoint +** 1 They overlap +** 2 P1 is completely contained within P2 +** 3 P2 is completely contained within P1 +** 4 P1 and P2 are the same polygon +** NULL Either P1 or P2 or both are not valid polygons +*/ +static void geopolyOverlapFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* +** Enable or disable debugging output +*/ +static void geopolyDebugFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ +#ifdef GEOPOLY_ENABLE_DEBUG + geo_debug = sqlite3_value_int(argv[0]); +#endif +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the geopoly virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int geopolyInit( + sqlite3 *db, /* Database connection */ + void *pAux, /* One of the RTREE_COORD_* constants */ + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ + char **pzErr, /* OUT: Error message, if any */ + int isCreate /* True for xCreate, false for xConnect */ +){ + int rc = SQLITE_OK; + Rtree *pRtree; + int nDb; /* Length of string argv[1] */ + int nName; /* Length of string argv[2] */ + sqlite3_str *pSql; + char *zSql; + int ii; + + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + + /* Allocate the sqlite3_vtab structure */ + nDb = (int)strlen(argv[1]); + nName = (int)strlen(argv[2]); + pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); + if( !pRtree ){ + return SQLITE_NOMEM; + } + memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); + pRtree->nBusy = 1; + pRtree->base.pModule = &rtreeModule; + pRtree->zDb = (char *)&pRtree[1]; + pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->eCoordType = RTREE_COORD_REAL32; + pRtree->nDim = 2; + pRtree->nDim2 = 4; + memcpy(pRtree->zDb, argv[1], nDb); + memcpy(pRtree->zName, argv[2], nName); + + + /* Create/Connect to the underlying relational database schema. If + ** that is successful, call sqlite3_declare_vtab() to configure + ** the r-tree table schema. + */ + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); + pRtree->nAux = 1; /* Add one for _shape */ + pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ + for(ii=3; iinAux++; + sqlite3_str_appendf(pSql, ",%s", argv[ii]); + } + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + sqlite3_free(zSql); + if( rc ) goto geopolyInit_fail; + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + if( rc ) goto geopolyInit_fail; + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); + if( rc ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + goto geopolyInit_fail; + } + + *ppVtab = (sqlite3_vtab *)pRtree; + return SQLITE_OK; + +geopolyInit_fail: + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; + assert( *ppVtab==0 ); + assert( pRtree->nBusy==1 ); + rtreeRelease(pRtree); + return rc; +} + + +/* +** GEOPOLY virtual table module xCreate method. +*/ +static int geopolyCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1); +} + +/* +** GEOPOLY virtual table module xConnect method. +*/ +static int geopolyConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0); +} + + +/* +** GEOPOLY virtual table module xFilter method. +** +** Query plans: +** +** 1 rowid lookup +** 2 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 3 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 4 full table scan +*/ +static int geopolyFilter( + sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ + int idxNum, /* Query plan */ + const char *idxStr, /* Not Used */ + int argc, sqlite3_value **argv /* Parameters to the query plan */ +){ + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeNode *pRoot = 0; + int rc = SQLITE_OK; + int iCell = 0; + sqlite3_stmt *pStmt; + + rtreeReference(pRtree); + + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ + freeCursorConstraints(pCsr); + sqlite3_free(pCsr->aPoint); + pStmt = pCsr->pReadAux; + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->pReadAux = pStmt; + + pCsr->iStrategy = idxNum; + if( idxNum==1 ){ + /* Special case - lookup by rowid. */ + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the leaf */ + i64 iRowid = sqlite3_value_int64(argv[0]); + i64 iNode = 0; + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = (u8)iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; + } + }else{ + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. + */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && idxNum<=3 ){ + RtreeCoord bbox[4]; + RtreeConstraint *p; + assert( argc==1 ); + geopolyBBox(0, argv[0], bbox, &rc); + if( rc ){ + goto geopoly_filter_end; + } + pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); + pCsr->nConstraint = 4; + if( p==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); + if( idxNum==2 ){ + /* Overlap query */ + p->op = 'B'; + p->iCoord = 0; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 1; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 2; + p->u.rValue = bbox[3].f; + p++; + p->op = 'D'; + p->iCoord = 3; + p->u.rValue = bbox[2].f; + }else{ + /* Within query */ + p->op = 'D'; + p->iCoord = 0; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 1; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 2; + p->u.rValue = bbox[2].f; + p++; + p->op = 'B'; + p->iCoord = 3; + p->u.rValue = bbox[3].f; + } + } + } + if( rc==SQLITE_OK ){ + RtreeSearchPoint *pNew; + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + goto geopoly_filter_end; + } + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; + pRoot = 0; + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); + rc = rtreeStepToLeaf(pCsr); + } + } + +geopoly_filter_end: + nodeRelease(pRtree, pRoot); + rtreeRelease(pRtree); + return rc; +} + +/* +** Rtree virtual table module xBestIndex method. There are three +** table scan strategies to choose from (in order from most to +** least desirable): +** +** idxNum idxStr Strategy +** ------------------------------------------------ +** 1 "rowid" Direct lookup by rowid. +** 2 "rtree" R-tree overlap query using geopoly_overlap() +** 3 "rtree" R-tree within query using geopoly_within() +** 4 "fullscan" full-table scan. +** ------------------------------------------------ +*/ +static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int ii; + int iRowidTerm = -1; + int iFuncTerm = -1; + int idxNum = 0; + + for(ii=0; iinConstraint; ii++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + if( !p->usable ) continue; + if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + iRowidTerm = ii; + break; + } + if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap() + ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within(). + ** See geopolyFindFunction() */ + iFuncTerm = ii; + idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2; + } + } + + if( iRowidTerm>=0 ){ + pIdxInfo->idxNum = 1; + pIdxInfo->idxStr = "rowid"; + pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; + pIdxInfo->estimatedCost = 30.0; + pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; + return SQLITE_OK; + } + if( iFuncTerm>=0 ){ + pIdxInfo->idxNum = idxNum; + pIdxInfo->idxStr = "rtree"; + pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0; + pIdxInfo->estimatedCost = 300.0; + pIdxInfo->estimatedRows = 10; + return SQLITE_OK; + } + pIdxInfo->idxNum = 4; + pIdxInfo->idxStr = "fullscan"; + pIdxInfo->estimatedCost = 3000000.0; + pIdxInfo->estimatedRows = 100000; + return SQLITE_OK; +} + + +/* +** GEOPOLY virtual table module xColumn method. +*/ +static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + Rtree *pRtree = (Rtree *)cur->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + + if( rc ) return rc; + if( p==0 ) return SQLITE_OK; + if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; + if( i<=pRtree->nAux ){ + if( !pCsr->bAuxValid ){ + if( pCsr->pReadAux==0 ){ + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + &pCsr->pReadAux, 0); + if( rc ) return rc; + } + sqlite3_bind_int64(pCsr->pReadAux, 1, + nodeGetRowid(pRtree, pNode, p->iCell)); + rc = sqlite3_step(pCsr->pReadAux); + if( rc==SQLITE_ROW ){ + pCsr->bAuxValid = 1; + }else{ + sqlite3_reset(pCsr->pReadAux); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + return rc; + } + } + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2)); + } + return SQLITE_OK; +} + + +/* +** The xUpdate method for GEOPOLY module virtual tables. +** +** For DELETE: +** +** argv[0] = the rowid to be deleted +** +** For INSERT: +** +** argv[0] = SQL NULL +** argv[1] = rowid to insert, or an SQL NULL to select automatically +** argv[2] = _shape column +** argv[3] = first application-defined column.... +** +** For UPDATE: +** +** argv[0] = rowid to modify. Never NULL +** argv[1] = rowid after the change. Never NULL +** argv[2] = new value for _shape +** argv[3] = new value for first application-defined column.... +*/ +static int geopolyUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **aData, + sqlite_int64 *pRowid +){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_OK; + RtreeCell cell; /* New cell to insert if nData>1 */ + i64 oldRowid; /* The old rowid */ + int oldRowidValid; /* True if oldRowid is valid */ + i64 newRowid; /* The new rowid */ + int newRowidValid; /* True if newRowid is valid */ + int coordChange = 0; /* Change in coordinates */ + + if( pRtree->nNodeRef ){ + /* Unable to write to the btree while another cursor is reading from it, + ** since the write might do a rebalance which would disrupt the read + ** cursor. */ + return SQLITE_LOCKED_VTAB; + } + rtreeReference(pRtree); + assert(nData>=1); + + oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; + oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; + newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; + newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; + cell.iRowid = newRowid; + + if( nData>1 /* not a DELETE */ + && (!oldRowidValid /* INSERT */ + || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ + || oldRowid!=newRowid) /* Rowid change */ + ){ + geopolyBBox(0, aData[2], cell.aCoord, &rc); + if( rc ){ + if( rc==SQLITE_ERROR ){ + pVtab->zErrMsg = + sqlite3_mprintf("_shape does not contain a valid polygon"); + } + goto geopoly_update_end; + } + coordChange = 1; + + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = rtreeConstraintError(pRtree, 0); + } + } + } + } + + /* If aData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){ + rc = rtreeDeleteRowid(pRtree, oldRowid); + } + + /* If the aData[] array contains more than one element, elements + ** (aData[2]..aData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 && coordChange ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf = 0; + if( !newRowidValid ){ + rc = rtreeNewRowid(pRtree, &cell.iRowid); + } + *pRowid = cell.iRowid; + if( rc==SQLITE_OK ){ + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); + } + if( rc==SQLITE_OK ){ + int rc2; + pRtree->iReinsertHeight = -1; + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + /* Change the data */ + if( rc==SQLITE_OK && nData>1 ){ + sqlite3_stmt *pUp = pRtree->pWriteAux; + int jj; + int nChange = 0; + sqlite3_bind_int64(pUp, 1, cell.iRowid); + assert( pRtree->nAux>=1 ); + if( sqlite3_value_nochange(aData[2]) ){ + sqlite3_bind_null(pUp, 2); + }else{ + GeoPoly *p = 0; + if( sqlite3_value_type(aData[2])==SQLITE_TEXT + && (p = geopolyFuncParam(0, aData[2], &rc))!=0 + && rc==SQLITE_OK + ){ + sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); + }else{ + sqlite3_bind_value(pUp, 2, aData[2]); + } + sqlite3_free(p); + nChange = 1; + } + for(jj=1; jjnAux; jj++){ + nChange++; + sqlite3_bind_value(pUp, jj+2, aData[jj+2]); + } + if( nChange ){ + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); + } + } + +geopoly_update_end: + rtreeRelease(pRtree); + return rc; +} + +/* +** Report that geopoly_overlap() is an overloaded function suitable +** for use in xBestIndex. +*/ +static int geopolyFindFunction( + sqlite3_vtab *pVtab, + int nArg, + const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg +){ + if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ + *pxFunc = geopolyOverlapFunc; + *ppArg = 0; + return SQLITE_INDEX_CONSTRAINT_FUNCTION; + } + if( sqlite3_stricmp(zName, "geopoly_within")==0 ){ + *pxFunc = geopolyWithinFunc; + *ppArg = 0; + return SQLITE_INDEX_CONSTRAINT_FUNCTION+1; + } + return 0; +} + + +static sqlite3_module geopolyModule = { + 2, /* iVersion */ + geopolyCreate, /* xCreate - create a table */ + geopolyConnect, /* xConnect - connect to an existing table */ + geopolyBestIndex, /* xBestIndex - Determine search strategy */ + rtreeDisconnect, /* xDisconnect - Disconnect from a table */ + rtreeDestroy, /* xDestroy - Drop a table */ + rtreeOpen, /* xOpen - open a cursor */ + rtreeClose, /* xClose - close a cursor */ + geopolyFilter, /* xFilter - configure scan constraints */ + rtreeNext, /* xNext - advance a cursor */ + rtreeEof, /* xEof */ + geopolyColumn, /* xColumn - read data */ + rtreeRowid, /* xRowid - read data */ + geopolyUpdate, /* xUpdate - write data */ + rtreeBeginTransaction, /* xBegin - begin transaction */ + rtreeEndTransaction, /* xSync - sync transaction */ + rtreeEndTransaction, /* xCommit - commit transaction */ + rtreeEndTransaction, /* xRollback - rollback transaction */ + geopolyFindFunction, /* xFindFunction - function overloading */ + rtreeRename, /* xRename - rename the table */ + rtreeSavepoint, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ +}; + +static int sqlite3_geopoly_init(sqlite3 *db){ + int rc = SQLITE_OK; + static const struct { + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + signed char nArg; + unsigned char bPure; + const char *zName; + } aFunc[] = { + { geopolyAreaFunc, 1, 1, "geopoly_area" }, + { geopolyBlobFunc, 1, 1, "geopoly_blob" }, + { geopolyJsonFunc, 1, 1, "geopoly_json" }, + { geopolySvgFunc, -1, 1, "geopoly_svg" }, + { geopolyWithinFunc, 2, 1, "geopoly_within" }, + { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" }, + { geopolyOverlapFunc, 2, 1, "geopoly_overlap" }, + { geopolyDebugFunc, 1, 0, "geopoly_debug" }, + { geopolyBBoxFunc, 1, 1, "geopoly_bbox" }, + { geopolyXformFunc, 7, 1, "geopoly_xform" }, + { geopolyRegularFunc, 4, 1, "geopoly_regular" }, + { geopolyReverseFunc, 1, 1, "geopoly_reverse" }, + }; + static const struct { + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); + const char *zName; + } aAgg[] = { + { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, + }; + int i; + for(i=0; inRef>0 ); p->nRef++; } } @@ -589,6 +604,7 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); pNode->zData = (u8 *)&pNode[1]; pNode->nRef = 1; + pRtree->nNodeRef++; pNode->pParent = pParent; pNode->isDirty = 1; nodeReference(pParent); @@ -622,10 +638,10 @@ static int nodeAcquire( /* Check if the requested node is already in the hash table. If so, ** increase its reference count and return it. */ - if( (pNode = nodeHashLookup(pRtree, iNode)) ){ + if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); if( pParent && !pNode->pParent ){ - nodeReference(pParent); + pParent->nRef++; pNode->pParent = pParent; } pNode->nRef++; @@ -664,6 +680,7 @@ static int nodeAcquire( pNode->pParent = pParent; pNode->zData = (u8 *)&pNode[1]; pNode->nRef = 1; + pRtree->nNodeRef++; pNode->iNode = iNode; pNode->isDirty = 0; pNode->pNext = 0; @@ -704,7 +721,10 @@ static int nodeAcquire( } *ppNode = pNode; }else{ - sqlite3_free(pNode); + if( pNode ){ + pRtree->nNodeRef--; + sqlite3_free(pNode); + } *ppNode = 0; } @@ -784,6 +804,7 @@ static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ sqlite3_step(p); pNode->isDirty = 0; rc = sqlite3_reset(p); + sqlite3_bind_null(p, 2); if( pNode->iNode==0 && rc==SQLITE_OK ){ pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); nodeHashInsert(pRtree, pNode); @@ -800,8 +821,10 @@ static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ int rc = SQLITE_OK; if( pNode ){ assert( pNode->nRef>0 ); + assert( pRtree->nNodeRef>0 ); pNode->nRef--; if( pNode->nRef==0 ){ + pRtree->nNodeRef--; if( pNode->iNode==1 ){ pRtree->iDepth = -1; } @@ -918,8 +941,9 @@ static void rtreeRelease(Rtree *pRtree){ pRtree->nBusy--; if( pRtree->nBusy==0 ){ pRtree->inWrTrans = 0; - pRtree->nCursor = 0; + assert( pRtree->nCursor==0 ); nodeBlobReset(pRtree); + assert( pRtree->nNodeRef==0 ); sqlite3_finalize(pRtree->pWriteNode); sqlite3_finalize(pRtree->pDeleteNode); sqlite3_finalize(pRtree->pReadRowid); @@ -928,6 +952,8 @@ static void rtreeRelease(Rtree *pRtree){ sqlite3_finalize(pRtree->pReadParent); sqlite3_finalize(pRtree->pWriteParent); sqlite3_finalize(pRtree->pDeleteParent); + sqlite3_finalize(pRtree->pWriteAux); + sqlite3_free(pRtree->zReadAuxSql); sqlite3_free(pRtree); } } @@ -1016,6 +1042,7 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){ RtreeCursor *pCsr = (RtreeCursor *)cur; assert( pRtree->nCursor>0 ); freeCursorConstraints(pCsr); + sqlite3_finalize(pCsr->pReadAux); sqlite3_free(pCsr->aPoint); for(ii=0; iiaNode[ii]); sqlite3_free(pCsr); @@ -1387,7 +1414,7 @@ static RtreeSearchPoint *rtreeSearchPointNew( if( iiaNode[ii]==0 ); pCur->aNode[ii] = pCur->aNode[0]; - }else{ + }else{ nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); } pCur->aNode[0] = 0; @@ -1558,6 +1585,10 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ /* Move to the next entry that matches the configured constraints. */ RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); + if( pCsr->bAuxValid ){ + pCsr->bAuxValid = 0; + sqlite3_reset(pCsr->pReadAux); + } rtreeSearchPointPop(pCsr); rc = rtreeStepToLeaf(pCsr); return rc; @@ -1592,7 +1623,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ if( p==0 ) return SQLITE_OK; if( i==0 ){ sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); - }else{ + }else if( i<=pRtree->nDim2 ){ nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ @@ -1603,7 +1634,27 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ assert( pRtree->eCoordType==RTREE_COORD_INT32 ); sqlite3_result_int(ctx, c.i); } - } + }else{ + if( !pCsr->bAuxValid ){ + if( pCsr->pReadAux==0 ){ + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + &pCsr->pReadAux, 0); + if( rc ) return rc; + } + sqlite3_bind_int64(pCsr->pReadAux, 1, + nodeGetRowid(pRtree, pNode, p->iCell)); + rc = sqlite3_step(pCsr->pReadAux); + if( rc==SQLITE_ROW ){ + pCsr->bAuxValid = 1; + }else{ + sqlite3_reset(pCsr->pReadAux); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + return rc; + } + } + sqlite3_result_value(ctx, + sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1)); + } return SQLITE_OK; } @@ -1681,14 +1732,17 @@ static int rtreeFilter( int ii; int rc = SQLITE_OK; int iCell = 0; + sqlite3_stmt *pStmt; rtreeReference(pRtree); /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ freeCursorConstraints(pCsr); sqlite3_free(pCsr->aPoint); + pStmt = pCsr->pReadAux; memset(pCsr, 0, sizeof(RtreeCursor)); pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->pReadAux = pStmt; pCsr->iStrategy = idxNum; if( idxNum==1 ){ @@ -1851,10 +1905,14 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ */ pIdxInfo->estimatedCost = 30.0; pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; return SQLITE_OK; } - if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ + if( p->usable + && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2) + || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) + ){ u8 op; switch( p->op ){ case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; @@ -2021,7 +2079,7 @@ static int ChooseLeaf( ){ int rc; int ii; - RtreeNode *pNode; + RtreeNode *pNode = 0; rc = nodeAcquire(pRtree, 1, 0, &pNode); for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ @@ -2427,7 +2485,7 @@ static int SplitNode( }else{ pLeft = pNode; pRight = nodeNew(pRtree, pLeft->pParent); - nodeReference(pLeft); + pLeft->nRef++; } if( !pLeft || !pRight ){ @@ -2836,7 +2894,7 @@ static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ /* ** Select a currently unused rowid for a new r-tree record. */ -static int newRowid(Rtree *pRtree, i64 *piRowid){ +static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){ int rc; sqlite3_bind_null(pRtree->pWriteRowid, 1); sqlite3_bind_null(pRtree->pWriteRowid, 2); @@ -2853,7 +2911,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ int rc; /* Return code */ RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */ int iCell; /* Index of iDelete cell in pLeaf */ - RtreeNode *pRoot; /* Root node of rtree structure */ + RtreeNode *pRoot = 0; /* Root node of rtree structure */ /* Obtain a reference to the root node to initialize Rtree.iDepth */ @@ -2896,7 +2954,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ */ if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ int rc2; - RtreeNode *pChild; + RtreeNode *pChild = 0; i64 iChild = nodeGetRowid(pRtree, pRoot, 0); rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); if( rc==SQLITE_OK ){ @@ -2917,6 +2975,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ rc = reinsertNodeContent(pRtree, pLeaf); } pRtree->pDeleted = pLeaf->pNext; + pRtree->nNodeRef--; sqlite3_free(pLeaf); } @@ -3013,7 +3072,7 @@ static int rtreeConstraintError(Rtree *pRtree, int iCol){ static int rtreeUpdate( sqlite3_vtab *pVtab, int nData, - sqlite3_value **azData, + sqlite3_value **aData, sqlite_int64 *pRowid ){ Rtree *pRtree = (Rtree *)pVtab; @@ -3021,6 +3080,12 @@ static int rtreeUpdate( RtreeCell cell; /* New cell to insert if nData>1 */ int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ + if( pRtree->nNodeRef ){ + /* Unable to write to the btree while another cursor is reading from it, + ** since the write might do a rebalance which would disrupt the read + ** cursor. */ + return SQLITE_LOCKED_VTAB; + } rtreeReference(pRtree); assert(nData>=1); @@ -3039,8 +3104,10 @@ static int rtreeUpdate( */ if( nData>1 ){ int ii; + int nn = nData - 4; - /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. + if( nn > pRtree->nDim2 ) nn = pRtree->nDim2; + /* Populate the cell.aCoord[] array. The first coordinate is aData[3]. ** ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared ** with "column" that are interpreted as table constraints. @@ -3048,13 +3115,12 @@ static int rtreeUpdate( ** This problem was discovered after years of use, so we silently ignore ** these kinds of misdeclared tables to avoid breaking any legacy. */ - assert( nData<=(pRtree->nDim2 + 3) ); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ - for(ii=0; iicell.aCoord[ii+1].f ){ rc = rtreeConstraintError(pRtree, ii+1); goto constraint; @@ -3063,9 +3129,9 @@ static int rtreeUpdate( }else #endif { - for(ii=0; iicell.aCoord[ii+1].i ){ rc = rtreeConstraintError(pRtree, ii+1); goto constraint; @@ -3075,10 +3141,10 @@ static int rtreeUpdate( /* If a rowid value was supplied, check if it is already present in ** the table. If so, the constraint has failed. */ - if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){ - cell.iRowid = sqlite3_value_int64(azData[2]); - if( sqlite3_value_type(azData[0])==SQLITE_NULL - || sqlite3_value_int64(azData[0])!=cell.iRowid + if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){ + cell.iRowid = sqlite3_value_int64(aData[2]); + if( sqlite3_value_type(aData[0])==SQLITE_NULL + || sqlite3_value_int64(aData[0])!=cell.iRowid ){ int steprc; sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); @@ -3097,16 +3163,16 @@ static int rtreeUpdate( } } - /* If azData[0] is not an SQL NULL value, it is the rowid of a + /* If aData[0] is not an SQL NULL value, it is the rowid of a ** record to delete from the r-tree table. The following block does ** just that. */ - if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ - rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0])); + if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){ + rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0])); } - /* If the azData[] array contains more than one element, elements - ** (azData[2]..azData[argc-1]) contain a new record to insert into + /* If the aData[] array contains more than one element, elements + ** (aData[2]..aData[argc-1]) contain a new record to insert into ** the r-tree structure. */ if( rc==SQLITE_OK && nData>1 ){ @@ -3115,7 +3181,7 @@ static int rtreeUpdate( /* Figure out the rowid of the new row. */ if( bHaveRowid==0 ){ - rc = newRowid(pRtree, &cell.iRowid); + rc = rtreeNewRowid(pRtree, &cell.iRowid); } *pRowid = cell.iRowid; @@ -3131,6 +3197,16 @@ static int rtreeUpdate( rc = rc2; } } + if( pRtree->nAux ){ + sqlite3_stmt *pUp = pRtree->pWriteAux; + int jj; + sqlite3_bind_int64(pUp, 1, *pRowid); + for(jj=0; jjnAux; jj++){ + sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]); + } + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); + } } constraint: @@ -3197,7 +3273,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ */ static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ Rtree *pRtree = (Rtree *)pVtab; - int iwt = pRtree->inWrTrans; + u8 iwt = pRtree->inWrTrans; UNUSED_PARAMETER(iSavepoint); pRtree->inWrTrans = 0; nodeBlobReset(pRtree); @@ -3287,18 +3363,18 @@ static int rtreeSqlInit( #define N_STATEMENT 8 static const char *azSql[N_STATEMENT] = { /* Write the xxx_node table */ - "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)", - "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1", + "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(?1, ?2)", + "DELETE FROM '%q'.'%q_node' WHERE nodeno = ?1", /* Read and write the xxx_rowid table */ - "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1", - "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)", - "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1", + "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = ?1", + "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(?1, ?2)", + "DELETE FROM '%q'.'%q_rowid' WHERE rowid = ?1", /* Read and write the xxx_parent table */ - "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1", - "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)", - "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1" + "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1", + "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)", + "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1" }; sqlite3_stmt **appStmt[N_STATEMENT]; int i; @@ -3306,14 +3382,25 @@ static int rtreeSqlInit( pRtree->db = db; if( isCreate ){ - char *zCreate = sqlite3_mprintf( -"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" -"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" -"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," - " parentnode INTEGER);" -"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", - zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize - ); + char *zCreate; + sqlite3_str *p = sqlite3_str_new(db); + int ii; + sqlite3_str_appendf(p, + "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY,nodeno", + zDb, zPrefix); + for(ii=0; iinAux; ii++){ + sqlite3_str_appendf(p,",a%d",ii); + } + sqlite3_str_appendf(p, + ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);", + zDb, zPrefix); + sqlite3_str_appendf(p, + "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);", + zDb, zPrefix); + sqlite3_str_appendf(p, + "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))", + zDb, zPrefix, pRtree->iNodeSize); + zCreate = sqlite3_str_finish(p); if( !zCreate ){ return SQLITE_NOMEM; } @@ -3335,7 +3422,17 @@ static int rtreeSqlInit( rc = rtreeQueryStat1(db, pRtree); for(i=0; inAux==0 ){ + zFormat = azSql[i]; + }else { + /* An UPSERT is very slightly slower than REPLACE, but it is needed + ** if there are auxiliary columns */ + zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)" + "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno"; + } + zSql = sqlite3_mprintf(zFormat, zDb, zPrefix); if( zSql ){ rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT, appStmt[i], 0); @@ -3344,6 +3441,36 @@ static int rtreeSqlInit( } sqlite3_free(zSql); } + if( pRtree->nAux ){ + pRtree->zReadAuxSql = sqlite3_mprintf( + "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", + zDb, zPrefix); + if( pRtree->zReadAuxSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_str *p = sqlite3_str_new(db); + int ii; + char *zSql; + sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); + for(ii=0; iinAux; ii++){ + if( ii ) sqlite3_str_append(p, ",", 1); + if( iinAuxNotNull ){ + sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); + }else{ + sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); + } + } + sqlite3_str_appendf(p, " WHERE rowid=?1"); + zSql = sqlite3_str_finish(p); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT, + &pRtree->pWriteAux, 0); + sqlite3_free(zSql); + } + } + } return rc; } @@ -3414,7 +3541,7 @@ static int getNodeSize( if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); }else if( pRtree->iNodeSize<(512-64) ){ - rc = SQLITE_CORRUPT; + rc = SQLITE_CORRUPT_VTAB; *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", pRtree->zName); } @@ -3446,17 +3573,22 @@ static int rtreeInit( int nDb; /* Length of string argv[1] */ int nName; /* Length of string argv[2] */ int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); + sqlite3_str *pSql; + char *zSql; + int ii = 4; + int iErr; const char *aErrMsg[] = { 0, /* 0 */ "Wrong number of columns for an rtree table", /* 1 */ "Too few columns for an rtree table", /* 2 */ - "Too many columns for an rtree table" /* 3 */ + "Too many columns for an rtree table", /* 3 */ + "Auxiliary rtree columns must be last" /* 4 */ }; - int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2; - if( aErrMsg[iErr] ){ - *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); + assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */ + if( argc>RTREE_MAX_AUX_COLUMN+3 ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[3]); return SQLITE_ERROR; } @@ -3474,53 +3606,73 @@ static int rtreeInit( pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; - pRtree->nDim = (u8)((argc-4)/2); - pRtree->nDim2 = pRtree->nDim*2; - pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; pRtree->eCoordType = (u8)eCoordType; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); - /* Figure out the node size to use. */ - rc = getNodeSize(db, pRtree, isCreate, pzErr); /* Create/Connect to the underlying relational database schema. If ** that is successful, call sqlite3_declare_vtab() to configure ** the r-tree table schema. */ - if( rc==SQLITE_OK ){ - if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){ - *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]); + for(ii=4; iinAux++; + sqlite3_str_appendf(pSql, ",%s", argv[ii]+1); + }else if( pRtree->nAux>0 ){ + break; }else{ - char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]); - char *zTmp; - int ii; - for(ii=4; zSql && iinDim2++; + sqlite3_str_appendf(pSql, ",%s", argv[ii]); } } - - if( rc==SQLITE_OK ){ - *ppVtab = (sqlite3_vtab *)pRtree; - }else{ - assert( *ppVtab==0 ); - assert( pRtree->nBusy==1 ); - rtreeRelease(pRtree); + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else if( iinDim = pRtree->nDim2/2; + if( pRtree->nDim<1 ){ + iErr = 2; + }else if( pRtree->nDim2>RTREE_MAX_DIMENSIONS*2 ){ + iErr = 3; + }else if( pRtree->nDim2 % 2 ){ + iErr = 1; + }else{ + iErr = 0; + } + if( iErr ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); + goto rtreeInit_fail; + } + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + if( rc ) goto rtreeInit_fail; + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); + if( rc ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + goto rtreeInit_fail; + } + + *ppVtab = (sqlite3_vtab *)pRtree; + return SQLITE_OK; + +rtreeInit_fail: + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; + assert( *ppVtab==0 ); + assert( pRtree->nBusy==1 ); + rtreeRelease(pRtree); return rc; } @@ -3608,6 +3760,478 @@ static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ } } +/* +** Context object passed between the various routines that make up the +** implementation of integrity-check function rtreecheck(). +*/ +typedef struct RtreeCheck RtreeCheck; +struct RtreeCheck { + sqlite3 *db; /* Database handle */ + const char *zDb; /* Database containing rtree table */ + const char *zTab; /* Name of rtree table */ + int bInt; /* True for rtree_i32 table */ + int nDim; /* Number of dimensions for this rtree tbl */ + sqlite3_stmt *pGetNode; /* Statement used to retrieve nodes */ + sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */ + int nLeaf; /* Number of leaf cells in table */ + int nNonLeaf; /* Number of non-leaf cells in table */ + int rc; /* Return code */ + char *zReport; /* Message to report */ + int nErr; /* Number of lines in zReport */ +}; + +#define RTREE_CHECK_MAX_ERROR 100 + +/* +** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error, +** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code. +*/ +static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){ + int rc = sqlite3_reset(pStmt); + if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc; +} + +/* +** The second and subsequent arguments to this function are a format string +** and printf style arguments. This function formats the string and attempts +** to compile it as an SQL statement. +** +** If successful, a pointer to the new SQL statement is returned. Otherwise, +** NULL is returned and an error code left in RtreeCheck.rc. +*/ +static sqlite3_stmt *rtreeCheckPrepare( + RtreeCheck *pCheck, /* RtreeCheck object */ + const char *zFmt, ... /* Format string and trailing args */ +){ + va_list ap; + char *z; + sqlite3_stmt *pRet = 0; + + va_start(ap, zFmt); + z = sqlite3_vmprintf(zFmt, ap); + + if( pCheck->rc==SQLITE_OK ){ + if( z==0 ){ + pCheck->rc = SQLITE_NOMEM; + }else{ + pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0); + } + } + + sqlite3_free(z); + va_end(ap); + return pRet; +} + +/* +** The second and subsequent arguments to this function are a printf() +** style format string and arguments. This function formats the string and +** appends it to the report being accumuated in pCheck. +*/ +static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ + va_list ap; + va_start(ap, zFmt); + if( pCheck->rc==SQLITE_OK && pCheck->nErrrc = SQLITE_NOMEM; + }else{ + pCheck->zReport = sqlite3_mprintf("%z%s%z", + pCheck->zReport, (pCheck->zReport ? "\n" : ""), z + ); + if( pCheck->zReport==0 ){ + pCheck->rc = SQLITE_NOMEM; + } + } + pCheck->nErr++; + } + va_end(ap); +} + +/* +** This function is a no-op if there is already an error code stored +** in the RtreeCheck object indicated by the first argument. NULL is +** returned in this case. +** +** Otherwise, the contents of rtree table node iNode are loaded from +** the database and copied into a buffer obtained from sqlite3_malloc(). +** If no error occurs, a pointer to the buffer is returned and (*pnNode) +** is set to the size of the buffer in bytes. +** +** Or, if an error does occur, NULL is returned and an error code left +** in the RtreeCheck object. The final value of *pnNode is undefined in +** this case. +*/ +static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ + u8 *pRet = 0; /* Return value */ + + assert( pCheck->rc==SQLITE_OK ); + if( pCheck->pGetNode==0 ){ + pCheck->pGetNode = rtreeCheckPrepare(pCheck, + "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", + pCheck->zDb, pCheck->zTab + ); + } + + if( pCheck->rc==SQLITE_OK ){ + sqlite3_bind_int64(pCheck->pGetNode, 1, iNode); + if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ + int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0); + const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0); + pRet = sqlite3_malloc(nNode); + if( pRet==0 ){ + pCheck->rc = SQLITE_NOMEM; + }else{ + memcpy(pRet, pNode, nNode); + *pnNode = nNode; + } + } + rtreeCheckReset(pCheck, pCheck->pGetNode); + if( pCheck->rc==SQLITE_OK && pRet==0 ){ + rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode); + } + } + + return pRet; +} + +/* +** This function is used to check that the %_parent (if bLeaf==0) or %_rowid +** (if bLeaf==1) table contains a specified entry. The schemas of the +** two tables are: +** +** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) +** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...) +** +** In both cases, this function checks that there exists an entry with +** IPK value iKey and the second column set to iVal. +** +*/ +static void rtreeCheckMapping( + RtreeCheck *pCheck, /* RtreeCheck object */ + int bLeaf, /* True for a leaf cell, false for interior */ + i64 iKey, /* Key for mapping */ + i64 iVal /* Expected value for mapping */ +){ + int rc; + sqlite3_stmt *pStmt; + const char *azSql[2] = { + "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1", + "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1" + }; + + assert( bLeaf==0 || bLeaf==1 ); + if( pCheck->aCheckMapping[bLeaf]==0 ){ + pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck, + azSql[bLeaf], pCheck->zDb, pCheck->zTab + ); + } + if( pCheck->rc!=SQLITE_OK ) return; + + pStmt = pCheck->aCheckMapping[bLeaf]; + sqlite3_bind_int64(pStmt, 1, iKey); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_DONE ){ + rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table", + iKey, iVal, (bLeaf ? "%_rowid" : "%_parent") + ); + }else if( rc==SQLITE_ROW ){ + i64 ii = sqlite3_column_int64(pStmt, 0); + if( ii!=iVal ){ + rtreeCheckAppendMsg(pCheck, + "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)", + iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal + ); + } + } + rtreeCheckReset(pCheck, pStmt); +} + +/* +** Argument pCell points to an array of coordinates stored on an rtree page. +** This function checks that the coordinates are internally consistent (no +** x1>x2 conditions) and adds an error message to the RtreeCheck object +** if they are not. +** +** Additionally, if pParent is not NULL, then it is assumed to point to +** the array of coordinates on the parent page that bound the page +** containing pCell. In this case it is also verified that the two +** sets of coordinates are mutually consistent and an error message added +** to the RtreeCheck object if they are not. +*/ +static void rtreeCheckCellCoord( + RtreeCheck *pCheck, + i64 iNode, /* Node id to use in error messages */ + int iCell, /* Cell number to use in error messages */ + u8 *pCell, /* Pointer to cell coordinates */ + u8 *pParent /* Pointer to parent coordinates */ +){ + RtreeCoord c1, c2; + RtreeCoord p1, p2; + int i; + + for(i=0; inDim; i++){ + readCoord(&pCell[4*2*i], &c1); + readCoord(&pCell[4*(2*i + 1)], &c2); + + /* printf("%e, %e\n", c1.u.f, c2.u.f); */ + if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){ + rtreeCheckAppendMsg(pCheck, + "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode + ); + } + + if( pParent ){ + readCoord(&pParent[4*2*i], &p1); + readCoord(&pParent[4*(2*i + 1)], &p2); + + if( (pCheck->bInt ? c1.ibInt ? c2.i>p2.i : c2.f>p2.f) + ){ + rtreeCheckAppendMsg(pCheck, + "Dimension %d of cell %d on node %lld is corrupt relative to parent" + , i, iCell, iNode + ); + } + } + } +} + +/* +** Run rtreecheck() checks on node iNode, which is at depth iDepth within +** the r-tree structure. Argument aParent points to the array of coordinates +** that bound node iNode on the parent node. +** +** If any problems are discovered, an error message is appended to the +** report accumulated in the RtreeCheck object. +*/ +static void rtreeCheckNode( + RtreeCheck *pCheck, + int iDepth, /* Depth of iNode (0==leaf) */ + u8 *aParent, /* Buffer containing parent coords */ + i64 iNode /* Node to check */ +){ + u8 *aNode = 0; + int nNode = 0; + + assert( iNode==1 || aParent!=0 ); + assert( pCheck->nDim>0 ); + + aNode = rtreeCheckGetNode(pCheck, iNode, &nNode); + if( aNode ){ + if( nNode<4 ){ + rtreeCheckAppendMsg(pCheck, + "Node %lld is too small (%d bytes)", iNode, nNode + ); + }else{ + int nCell; /* Number of cells on page */ + int i; /* Used to iterate through cells */ + if( aParent==0 ){ + iDepth = readInt16(aNode); + if( iDepth>RTREE_MAX_DEPTH ){ + rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth); + sqlite3_free(aNode); + return; + } + } + nCell = readInt16(&aNode[2]); + if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){ + rtreeCheckAppendMsg(pCheck, + "Node %lld is too small for cell count of %d (%d bytes)", + iNode, nCell, nNode + ); + }else{ + for(i=0; inDim*2*4)]; + i64 iVal = readInt64(pCell); + rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent); + + if( iDepth>0 ){ + rtreeCheckMapping(pCheck, 0, iVal, iNode); + rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal); + pCheck->nNonLeaf++; + }else{ + rtreeCheckMapping(pCheck, 1, iVal, iNode); + pCheck->nLeaf++; + } + } + } + } + sqlite3_free(aNode); + } +} + +/* +** The second argument to this function must be either "_rowid" or +** "_parent". This function checks that the number of entries in the +** %_rowid or %_parent table is exactly nExpect. If not, it adds +** an error message to the report in the RtreeCheck object indicated +** by the first argument. +*/ +static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){ + if( pCheck->rc==SQLITE_OK ){ + sqlite3_stmt *pCount; + pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'", + pCheck->zDb, pCheck->zTab, zTbl + ); + if( pCount ){ + if( sqlite3_step(pCount)==SQLITE_ROW ){ + i64 nActual = sqlite3_column_int64(pCount, 0); + if( nActual!=nExpect ){ + rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table" + " - expected %lld, actual %lld" , zTbl, nExpect, nActual + ); + } + } + pCheck->rc = sqlite3_finalize(pCount); + } + } +} + +/* +** This function does the bulk of the work for the rtree integrity-check. +** It is called by rtreecheck(), which is the SQL function implementation. +*/ +static int rtreeCheckTable( + sqlite3 *db, /* Database handle to access db through */ + const char *zDb, /* Name of db ("main", "temp" etc.) */ + const char *zTab, /* Name of rtree table to check */ + char **pzReport /* OUT: sqlite3_malloc'd report text */ +){ + RtreeCheck check; /* Common context for various routines */ + sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ + int bEnd = 0; /* True if transaction should be closed */ + int nAux = 0; /* Number of extra columns. */ + + /* Initialize the context object */ + memset(&check, 0, sizeof(check)); + check.db = db; + check.zDb = zDb; + check.zTab = zTab; + + /* If there is not already an open transaction, open one now. This is + ** to ensure that the queries run as part of this integrity-check operate + ** on a consistent snapshot. */ + if( sqlite3_get_autocommit(db) ){ + check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); + bEnd = 1; + } + + /* Find the number of auxiliary columns */ + if( check.rc==SQLITE_OK ){ + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); + if( pStmt ){ + nAux = sqlite3_column_count(pStmt) - 2; + sqlite3_finalize(pStmt); + } + check.rc = SQLITE_OK; + } + + /* Find number of dimensions in the rtree table. */ + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab); + if( pStmt ){ + int rc; + check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2; + if( check.nDim<1 ){ + rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree"); + }else if( SQLITE_ROW==sqlite3_step(pStmt) ){ + check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER); + } + rc = sqlite3_finalize(pStmt); + if( rc!=SQLITE_CORRUPT ) check.rc = rc; + } + + /* Do the actual integrity-check */ + if( check.nDim>=1 ){ + if( check.rc==SQLITE_OK ){ + rtreeCheckNode(&check, 0, 0, 1); + } + rtreeCheckCount(&check, "_rowid", check.nLeaf); + rtreeCheckCount(&check, "_parent", check.nNonLeaf); + } + + /* Finalize SQL statements used by the integrity-check */ + sqlite3_finalize(check.pGetNode); + sqlite3_finalize(check.aCheckMapping[0]); + sqlite3_finalize(check.aCheckMapping[1]); + + /* If one was opened, close the transaction */ + if( bEnd ){ + int rc = sqlite3_exec(db, "END", 0, 0, 0); + if( check.rc==SQLITE_OK ) check.rc = rc; + } + *pzReport = check.zReport; + return check.rc; +} + +/* +** Usage: +** +** rtreecheck(); +** rtreecheck(, ); +** +** Invoking this SQL function runs an integrity-check on the named rtree +** table. The integrity-check verifies the following: +** +** 1. For each cell in the r-tree structure (%_node table), that: +** +** a) for each dimension, (coord1 <= coord2). +** +** b) unless the cell is on the root node, that the cell is bounded +** by the parent cell on the parent node. +** +** c) for leaf nodes, that there is an entry in the %_rowid +** table corresponding to the cell's rowid value that +** points to the correct node. +** +** d) for cells on non-leaf nodes, that there is an entry in the +** %_parent table mapping from the cell's child node to the +** node that it resides on. +** +** 2. That there are the same number of entries in the %_rowid table +** as there are leaf cells in the r-tree structure, and that there +** is a leaf cell that corresponds to each entry in the %_rowid table. +** +** 3. That there are the same number of entries in the %_parent table +** as there are non-leaf cells in the r-tree structure, and that +** there is a non-leaf cell that corresponds to each entry in the +** %_parent table. +*/ +static void rtreecheck( + sqlite3_context *ctx, + int nArg, + sqlite3_value **apArg +){ + if( nArg!=1 && nArg!=2 ){ + sqlite3_result_error(ctx, + "wrong number of arguments to function rtreecheck()", -1 + ); + }else{ + int rc; + char *zReport = 0; + const char *zDb = (const char*)sqlite3_value_text(apArg[0]); + const char *zTab; + if( nArg==1 ){ + zTab = zDb; + zDb = "main"; + }else{ + zTab = (const char*)sqlite3_value_text(apArg[1]); + } + rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport); + if( rc==SQLITE_OK ){ + sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT); + }else{ + sqlite3_result_error_code(ctx, rc); + } + sqlite3_free(zReport); + } +} + +/* Conditionally include the geopoly code */ +#ifdef SQLITE_ENABLE_GEOPOLY +# include "geopoly.c" +#endif + /* ** Register the r-tree module with database handle db. This creates the ** virtual table module "rtree" and the debugging/analysis scalar @@ -3621,6 +4245,9 @@ int sqlite3RtreeInit(sqlite3 *db){ if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0); + } if( rc==SQLITE_OK ){ #ifdef SQLITE_RTREE_INT_ONLY void *c = (void *)RTREE_COORD_INT32; @@ -3633,6 +4260,11 @@ int sqlite3RtreeInit(sqlite3 *db){ void *c = (void *)RTREE_COORD_INT32; rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); } +#ifdef SQLITE_ENABLE_GEOPOLY + if( rc==SQLITE_OK ){ + rc = sqlite3_geopoly_init(db); + } +#endif return rc; } diff --git a/ext/rtree/rtree.h b/ext/rtree/rtree.h index 1fdbcccc5e..8f41500db1 100644 --- a/ext/rtree/rtree.h +++ b/ext/rtree/rtree.h @@ -15,6 +15,10 @@ */ #include "sqlite3.h" +#ifdef SQLITE_OMIT_VIRTUALTABLE +# undef SQLITE_ENABLE_RTREE +#endif + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index becc8e1a97..bdaad542d2 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -476,11 +476,11 @@ foreach {tn sql_template testdata} { } 3 "UPDATE %CONF% t1 SET idx = 2 WHERE idx = 4" { - ROLLBACK 1 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6} - ABORT 1 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} - IGNORE 1 0 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} - FAIL 1 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} - REPLACE 1 0 {1 1 2 3 4 2 4 5 6 7 3 3 4 5 6} + ROLLBACK 0 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6} + ABORT 0 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} + IGNORE 0 0 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} + FAIL 0 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} + REPLACE 0 0 {1 1 2 3 4 2 4 5 6 7 3 3 4 5 6} } 3 "UPDATE %CONF% t1 SET idx = ((idx+1)%5)+1 WHERE idx > 2" { @@ -519,7 +519,7 @@ foreach {tn sql_template testdata} { do_test $testname.2 [list sql_uses_stmt db $sql] $uses do_execsql_test $testname.3 { SELECT * FROM t1 ORDER BY idx } $data - do_test $testname.4 { rtree_check db t1 } 0 + do_rtree_integrity_test $testname.4 t1 db close } } @@ -609,4 +609,43 @@ do_execsql_test 15.2 { COMMIT; } +# Test cases for the new auxiliary columns feature +# +do_catchsql_test 16.100 { + CREATE VIRTUAL TABLE t16 USING rtree(id,x0,x1,y0,+aux1,x1); +} {1 {Auxiliary rtree columns must be last}} +do_test 16.110 { + set sql { + CREATE VIRTUAL TABLE t16 USING rtree( + id, x00, x01, x10, x11, x20, x21, x30, x31, x40, x41 + } + for {set i 12} {$i<=100} {incr i} { + append sql ", +a$i" + } + append sql ");" + execsql $sql +} {} +do_test 16.120 { + set sql { + CREATE VIRTUAL TABLE t16b USING rtree( + id, x00, x01, x10, x11, x20, x21, x30, x31, x40, x41 + } + for {set i 12} {$i<=101} {incr i} { + append sql ", +a$i" + } + append sql ");" + catchsql $sql +} {1 {Too many columns for an rtree table}} + +do_execsql_test 16.130 { + DROP TABLE IF EXISTS rt1; + CREATE VIRTUAL TABLE rt1 USING rtree(id, x1, x2, +aux); + INSERT INTO rt1 VALUES(1, 1, 2, 'aux1'); + INSERT INTO rt1 VALUES(2, 2, 3, 'aux2'); + INSERT INTO rt1 VALUES(3, 3, 4, 'aux3'); + INSERT INTO rt1 VALUES(4, 4, 5, 'aux4'); + SELECT * FROM rt1 WHERE id IN (1, 2, 3, 4); +} {1 1.0 2.0 aux1 2 2.0 3.0 aux2 3 3.0 4.0 aux3 4 4.0 5.0 aux4} + +expand_all_sql db finish_test diff --git a/ext/rtree/rtree2.test b/ext/rtree/rtree2.test index f5d15cc6b9..853737b9c7 100644 --- a/ext/rtree/rtree2.test +++ b/ext/rtree/rtree2.test @@ -81,9 +81,7 @@ foreach module {rtree_i32 rtree} { set rc } {1} - do_test rtree2-$module.$nDim.3 { - rtree_check db t1 - } 0 + do_rtree_integrity_test rtree2-$module.$nDim.3 t1 set OPS [list < > <= >= =] for {set ii 0} {$ii < $::NSELECT} {incr ii} { @@ -133,9 +131,7 @@ foreach module {rtree_i32 rtree} { } set rc } {1} - do_test rtree2-$module.$nDim.5.$ii.2 { - rtree_check db t1 - } {0} + do_rtree_integrity_test rtree2-$module.$nDim.5.$ii.2 t1 } do_test rtree2-$module.$nDim.6 { diff --git a/ext/rtree/rtree3.test b/ext/rtree/rtree3.test index 1d863c6cc2..e37d18ee84 100644 --- a/ext/rtree/rtree3.test +++ b/ext/rtree/rtree3.test @@ -81,7 +81,7 @@ do_faultsim_test rtree3-2 -faults oom* -prep { do_malloc_test rtree3-3.prep { faultsim_delete_and_reopen execsql { - CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2); + CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2, +a1, +a2); INSERT INTO rt VALUES(NULL, 3, 5, 7, 9); } faultsim_save_and_close diff --git a/ext/rtree/rtree4.test b/ext/rtree/rtree4.test index a3872b0735..a73921d8d5 100644 --- a/ext/rtree/rtree4.test +++ b/ext/rtree/rtree4.test @@ -15,6 +15,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { @@ -246,6 +247,8 @@ for {set nDim 1} {$nDim<=5} {incr nDim} { } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] } + do_rtree_integrity_test rtree4-$nDim.3 rx } +expand_all_sql db finish_test diff --git a/ext/rtree/rtree5.test b/ext/rtree/rtree5.test index 8ff90b0cb7..92bb6905c7 100644 --- a/ext/rtree/rtree5.test +++ b/ext/rtree/rtree5.test @@ -16,6 +16,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { @@ -76,5 +77,7 @@ do_test rtree5-1.13 { y1=-2147483648 AND y2=-2147483643 } } {2 2147483643 2147483647 -2147483648 -2147483643} +do_rtree_integrity_test rtree5-1.14 t1 +expand_all_sql db finish_test diff --git a/ext/rtree/rtree6.test b/ext/rtree/rtree6.test index c9c87e8ad9..6800b4bb10 100644 --- a/ext/rtree/rtree6.test +++ b/ext/rtree/rtree6.test @@ -74,42 +74,48 @@ do_test rtree6-1.5 { do_eqp_test rtree6.2.1 { SELECT * FROM t1,t2 WHERE k=+ii AND x1<10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} - 0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0 + `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) } do_eqp_test rtree6.2.2 { SELECT * FROM t1,t2 WHERE k=ii AND x1<10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} - 0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0 + `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) } do_eqp_test rtree6.2.3 { SELECT * FROM t1,t2 WHERE k=ii } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:} - 0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2: + `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) } do_eqp_test rtree6.2.4.1 { SELECT * FROM t1,t2 WHERE v=+ii and x1<10 and x2>10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1} - 0 1 1 {SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1 + `--SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?) } do_eqp_test rtree6.2.4.2 { SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1} - 0 1 1 {SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1 + `--SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?) } do_eqp_test rtree6.2.5 { SELECT * FROM t1,t2 WHERE k=ii AND x10.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>1.1 } {} - +expand_all_sql db finish_test diff --git a/ext/rtree/rtree7.test b/ext/rtree/rtree7.test index 4eee4c219a..1556179c4f 100644 --- a/ext/rtree/rtree7.test +++ b/ext/rtree/rtree7.test @@ -17,6 +17,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree||!vacuum { @@ -67,4 +68,6 @@ do_test rtree7-1.5 { } } {51 102 153 204} +do_rtree_integrity_test rtree7-1.6 rt + finish_test diff --git a/ext/rtree/rtree8.test b/ext/rtree/rtree8.test index 024d098e07..68b68c45fd 100644 --- a/ext/rtree/rtree8.test +++ b/ext/rtree/rtree8.test @@ -14,6 +14,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { finish_test ; return } @@ -37,11 +38,20 @@ do_test rtree8-1.1.1 { } {} do_test rtree8-1.1.2 { set res [list] - db eval { SELECT * FROM t1 } { - lappend res $x1 $x2 + set rc [catch { + db eval { SELECT * FROM t1 } { + lappend res $x1 $x2 + if {$id==3} { db eval { DELETE FROM t1 WHERE id>3 } } + } + } msg]; + lappend rc $msg + set rc +} {1 {database table is locked}} +do_test rtree8-1.1.2b { + db eval { SELECT * FROM t1 ORDER BY +id } { if {$id==3} { db eval { DELETE FROM t1 WHERE id>3 } } } - set res + db eval {SELECT x1, x2 FROM t1} } {1 3 2 4 3 5} do_test rtree8-1.1.3 { execsql { SELECT * FROM t1 } @@ -64,6 +74,7 @@ do_test rtree8-1.2.2 { nested_select 1 } {51} # nodes internally. # populate_t1 1500 +do_rtree_integrity_test rtree8-1.3.0 t1 do_execsql_test rtree8-1.3.1 { SELECT max(nodeno) FROM t1_node } {164} do_test rtree8-1.3.2 { set rowids [execsql {SELECT min(rowid) FROM t1_rowid GROUP BY nodeno}] @@ -158,13 +169,39 @@ do_test rtree8-5.2 { } execsql COMMIT } {} -do_test rtree8-5.3 { +do_rtree_integrity_test rtree8-5.3 t2 +do_test rtree8-5.4 { execsql BEGIN for {set i 0} {$i < 200} {incr i} { execsql { DELETE FROM t2 WHERE id = $i } } execsql COMMIT } {} +do_rtree_integrity_test rtree8-5.5 t2 + +# 2018-05-24 +# The following script caused an assertion fault and/or segfault +# prior to the fix that prevents simultaneous reads and writes on +# the same rtree virtual table. +# +do_test rtree8-6.1 { + db close + sqlite3 db :memory: + db eval { + PRAGMA page_size=512; + CREATE VIRTUAL TABLE t1 USING rtree(id,x1,x2,y1,y2); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<49) + INSERT INTO t1 SELECT x, x, x+1, x, x+1 FROM c; + } + set rc [catch { + db eval {SELECT id FROM t1} x { + db eval {DELETE FROM t1 WHERE id=$x(id)} + } + } msg] + lappend rc $msg +} {1 {database table is locked}} + + finish_test diff --git a/ext/rtree/rtree9.test b/ext/rtree/rtree9.test index b2361b2bd0..a7cd344d76 100644 --- a/ext/rtree/rtree9.test +++ b/ext/rtree/rtree9.test @@ -15,6 +15,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { finish_test ; return } ifcapable rtree_int_only { finish_test; return } @@ -42,6 +43,7 @@ for {set i 0} {$i < 1000} {incr i} { set z [expr ($i/100)%10] execsql { INSERT INTO rt VALUES($i, $x, $x+1, $y, $y+1, $z, $z+1) } } +do_rtree_integrity_test rtree9-2.0 rt do_execsql_test rtree9-2.1 { SELECT id FROM rt WHERE id MATCH cube(2.5, 2.5, 2.5, 1, 1, 1) ORDER BY id; } {222 223 232 233 322 323 332 333} @@ -50,7 +52,7 @@ do_execsql_test rtree9-2.2 { } {555 556 565 566 655 656 665 666} -do_execsql_test rtree9-3.1 { +do_execsql_test rtree9-3.0 { CREATE VIRTUAL TABLE rt32 USING rtree_i32(id, x1, x2, y1, y2, z1, z2); } {} for {set i 0} {$i < 1000} {incr i} { @@ -59,6 +61,7 @@ for {set i 0} {$i < 1000} {incr i} { set z [expr ($i/100)%10] execsql { INSERT INTO rt32 VALUES($i, $x, $x+1, $y, $y+1, $z, $z+1) } } +do_rtree_integrity_test rtree9-3.1 rt32 do_execsql_test rtree9-3.2 { SELECT id FROM rt32 WHERE id MATCH cube(3, 3, 3, 1, 1, 1) ORDER BY id; } {222 223 224 232 233 234 242 243 244 322 323 324 332 333 334 342 343 344 422 423 424 432 433 434 442 443 444} @@ -121,5 +124,6 @@ do_execsql_test rtree9-5.3 { UPDATE rt2 SET xmin=xmin+5, ymin=ymin+5, xmax=xmax+5, ymax=ymax+5; SELECT id FROM rt2 WHERE id MATCH circle(5.0, 5.0, 2.0); } {1 2 3 4 13 14 15 16 17} +do_rtree_integrity_test rtree9-5.4 rt2 finish_test diff --git a/ext/rtree/rtreeA.test b/ext/rtree/rtreeA.test index fa41dc95dd..190d7d7532 100644 --- a/ext/rtree/rtreeA.test +++ b/ext/rtree/rtreeA.test @@ -108,6 +108,12 @@ do_corruption_tests rtreeA-1.1 { 4 "SELECT * FROM t1 WHERE x1<10 AND x2>12" } +do_execsql_test rtreeA-1.1.1 { + SELECT rtreecheck('main', 't1') +} {{Node 1 missing from database +Wrong number of entries in %_rowid table - expected 0, actual 500 +Wrong number of entries in %_parent table - expected 0, actual 23}} + do_execsql_test rtreeA-1.2.0 { DROP TABLE t1_node } {} do_corruption_tests rtreeA-1.2 -error "database disk image is malformed" { 1 "SELECT * FROM t1" @@ -157,6 +163,10 @@ do_corruption_tests rtreeA-3.1 { 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" } +do_execsql_test rtreeA-3.1.0.3 { + SELECT rtreecheck('main', 't1')!="ok" +} {1} + do_test rtreeA-3.2.0 { set_tree_depth t1 1000 } {1000} do_corruption_tests rtreeA-3.2 { 1 "SELECT * FROM t1" @@ -176,6 +186,12 @@ do_corruption_tests rtreeA-3.3 { 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" } +do_execsql_test rtreeA-3.3.3.4 { + SELECT rtreecheck('main', 't1') +} {{Rtree depth out of range (65535) +Wrong number of entries in %_rowid table - expected 0, actual 499 +Wrong number of entries in %_parent table - expected 0, actual 23}} + #------------------------------------------------------------------------- # Set the "number of entries" field on some nodes incorrectly. # @@ -203,6 +219,10 @@ do_corruption_tests rtreeA-5.1 { 2 "DELETE FROM t1" } +do_execsql_test rtreeA-5.2 { + SELECT rtreecheck('main', 't1')!="ok" +} {1} + #------------------------------------------------------------------------- # Add some bad entries to the %_parent table. # @@ -216,6 +236,10 @@ do_corruption_tests rtreeA-6.1 { 2 "UPDATE t1 SET x1=x1+1, x2=x2+1" } +do_execsql_test rtreeA-6.2 { + SELECT rtreecheck('main', 't1')!="ok" +} {1} + #------------------------------------------------------------------------- # Truncated blobs in the _node table. # @@ -228,6 +252,10 @@ do_execsql_test rtreeA-7.100 { do_catchsql_test rtreeA-7.110 { SELECT * FROM t1 WHERE x1>0 AND x1<100 AND x2>0 AND x2<100; } {1 {undersize RTree blobs in "t1_node"}} +do_test rtreeA-7.120 { + sqlite3_extended_errcode db +} {SQLITE_CORRUPT_VTAB} finish_test + diff --git a/ext/rtree/rtreeB.test b/ext/rtree/rtreeB.test index aeb308eca7..6fc31042ca 100644 --- a/ext/rtree/rtreeB.test +++ b/ext/rtree/rtreeB.test @@ -15,6 +15,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { finish_test ; return } @@ -44,4 +45,6 @@ ifcapable rtree_int_only { } {{{1073741824 0 0 100 100} {2147483646 0 0 200 200} {4294967296 0 0 300 300} {8589934592 20 20 150 150} {9223372036854775807 150 150 400 400}}} } +do_rtree_integrity_test rtreeB-1.2 t1 + finish_test diff --git a/ext/rtree/rtreeC.test b/ext/rtree/rtreeC.test index a26c401e0d..19a1f7fe6c 100644 --- a/ext/rtree/rtreeC.test +++ b/ext/rtree/rtreeC.test @@ -15,6 +15,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { finish_test ; return } set testprefix rtreeC @@ -28,31 +29,35 @@ do_eqp_test 1.1 { SELECT * FROM r_tree, t WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { - 0 0 1 {SCAN TABLE t} - 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} + QUERY PLAN + |--SCAN TABLE t + `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0 } do_eqp_test 1.2 { SELECT * FROM t, r_tree WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { - 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} + QUERY PLAN + |--SCAN TABLE t + `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0 } do_eqp_test 1.3 { SELECT * FROM t, r_tree WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y } { - 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} + QUERY PLAN + |--SCAN TABLE t + `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0 } do_eqp_test 1.5 { SELECT * FROM t, r_tree } { - 0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:} - 0 1 0 {SCAN TABLE t} + QUERY PLAN + |--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2: + `--SCAN TABLE t } do_execsql_test 2.0 { @@ -81,31 +86,35 @@ do_eqp_test 2.1 { SELECT * FROM r_tree, t WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { - 0 0 1 {SCAN TABLE t} - 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} + QUERY PLAN + |--SCAN TABLE t + `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0 } do_eqp_test 2.2 { SELECT * FROM t, r_tree WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { - 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} + QUERY PLAN + |--SCAN TABLE t + `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0 } do_eqp_test 2.3 { SELECT * FROM t, r_tree WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y } { - 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} + QUERY PLAN + |--SCAN TABLE t + `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0 } do_eqp_test 2.5 { SELECT * FROM t, r_tree } { - 0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:} - 0 1 0 {SCAN TABLE t} + QUERY PLAN + |--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2: + `--SCAN TABLE t } #------------------------------------------------------------------------- @@ -118,20 +127,25 @@ do_execsql_test 3.1 { } do_eqp_test 3.2.1 { SELECT * FROM t1 CROSS JOIN t2 } { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE t2} + QUERY PLAN + |--SCAN TABLE t1 + `--SCAN TABLE t2 } do_eqp_test 3.2.2 { SELECT * FROM t2 CROSS JOIN t1 } { - 0 0 0 {SCAN TABLE t2} 0 1 1 {SCAN TABLE t1} + QUERY PLAN + |--SCAN TABLE t2 + `--SCAN TABLE t1 } do_eqp_test 3.3.1 { SELECT * FROM t1 CROSS JOIN t3 } { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:} + QUERY PLAN + |--SCAN TABLE t1 + `--SCAN TABLE t3 VIRTUAL TABLE INDEX 2: } do_eqp_test 3.3.2 { SELECT * FROM t3 CROSS JOIN t1 } { - 0 0 0 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:} - 0 1 1 {SCAN TABLE t1} + QUERY PLAN + |--SCAN TABLE t3 VIRTUAL TABLE INDEX 2: + `--SCAN TABLE t1 } #-------------------------------------------------------------------- @@ -164,7 +178,7 @@ do_execsql_test 4.3 { reset_db do_execsql_test 5.1 { CREATE TABLE t1(x PRIMARY KEY, y); - CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2); + CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, +d1); INSERT INTO t1(x) VALUES(1); INSERT INTO t1(x) SELECT x+1 FROM t1; -- 2 @@ -178,8 +192,9 @@ do_execsql_test 5.1 { INSERT INTO t1(x) SELECT x+256 FROM t1; -- 512 INSERT INTO t1(x) SELECT x+512 FROM t1; --1024 - INSERT INTO rt SELECT x, x, x+1 FROM t1 WHERE x<=5; + INSERT INTO rt SELECT x, x, x+1, printf('x%04xy',x) FROM t1 WHERE x<=5; } +do_rtree_integrity_test 5.1.1 rt # First test a query with no ANALYZE data at all. The outer loop is # real table "t1". @@ -187,8 +202,9 @@ do_execsql_test 5.1 { do_eqp_test 5.2 { SELECT * FROM t1, rt WHERE x==id; } { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:} + QUERY PLAN + |--SCAN TABLE t1 + `--SCAN TABLE rt VIRTUAL TABLE INDEX 1: } # Now create enough ANALYZE data to tell SQLite that virtual table "rt" @@ -203,8 +219,9 @@ sqlite3 db test.db do_eqp_test 5.4 { SELECT * FROM t1, rt WHERE x==id; } { - 0 0 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:} - 0 1 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)} + QUERY PLAN + |--SCAN TABLE rt VIRTUAL TABLE INDEX 2: + `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?) } # Delete the ANALYZE data. "t1" should be the outer loop again. @@ -215,8 +232,9 @@ sqlite3 db test.db do_eqp_test 5.6 { SELECT * FROM t1, rt WHERE x==id; } { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:} + QUERY PLAN + |--SCAN TABLE t1 + `--SCAN TABLE rt VIRTUAL TABLE INDEX 1: } # This time create and attach a database that contains ANALYZE data for @@ -239,8 +257,9 @@ do_test 5.7 { do_eqp_test 5.8 { SELECT * FROM t1, rt WHERE x==id; } { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:} + QUERY PLAN + |--SCAN TABLE t1 + `--SCAN TABLE rt VIRTUAL TABLE INDEX 1: } #-------------------------------------------------------------------- @@ -297,9 +316,9 @@ do_execsql_test 7.0 { } -proc do_eqp_execsql_test {tn sql res} { - set query "EXPLAIN QUERY PLAN $sql ; $sql " - uplevel [list do_execsql_test $tn $query $res] +proc do_eqp_execsql_test {tn sql res1 res2} { + do_eqp_test $tn.1 $sql $res1 + do_execsql_test $tn.2 $sql $res2 } do_eqp_execsql_test 7.1 { @@ -307,9 +326,11 @@ do_eqp_execsql_test 7.1 { ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { - 0 0 0 {SCAN TABLE xdir} - 0 1 2 {SCAN TABLE ydir} - 0 2 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1} + QUERY PLAN + |--SCAN TABLE xdir + |--SCAN TABLE ydir + `--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1 +} { 2 4 } @@ -318,10 +339,11 @@ do_eqp_execsql_test 7.2 { ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { - 0 0 0 {SCAN TABLE xdir} - 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1} - 0 2 2 {SCAN TABLE ydir} - + QUERY PLAN + |--SCAN TABLE xdir + |--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1 + `--SCAN TABLE ydir +} { 5 1 2 7 12 14 {} 5 2 2 7 8 12 10 5 4 5 5 10 10 10 @@ -332,9 +354,11 @@ do_eqp_execsql_test 7.3 { ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { - 0 0 0 {SCAN TABLE xdir} - 0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1} - 0 2 2 {SCAN TABLE ydir} + QUERY PLAN + |--SCAN TABLE xdir + |--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1 + `--SCAN TABLE ydir +} { 2 4 } @@ -343,9 +367,11 @@ do_eqp_execsql_test 7.4 { ON (y1 BETWEEN ymin AND ymax) WHERE (x1 BETWEEN xmin AND xmax); } { - 0 0 1 {SCAN TABLE xdir} - 0 1 0 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1} - 0 2 2 {SCAN TABLE ydir} + QUERY PLAN + |--SCAN TABLE xdir + |--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1 + `--SCAN TABLE ydir +} { 2 4 } diff --git a/ext/rtree/rtreeE.test b/ext/rtree/rtreeE.test index 3e5ba3a67f..72dcc94c9f 100644 --- a/ext/rtree/rtreeE.test +++ b/ext/rtree/rtreeE.test @@ -15,6 +15,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { finish_test ; return } ifcapable rtree_int_only { finish_test; return } @@ -25,7 +26,7 @@ ifcapable rtree_int_only { finish_test; return } # register_circle_geom db -do_execsql_test rtreeE-1.1 { +do_execsql_test rtreeE-1.0.0 { PRAGMA page_size=512; CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1); @@ -47,6 +48,7 @@ do_execsql_test rtreeE-1.1 { y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4) INSERT INTO rt1 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y; } {} +do_rtree_integrity_test rtreeE-1.0.1 rt1 # Queries against each of the three clusters */ do_execsql_test rtreeE-1.1 { @@ -111,6 +113,7 @@ do_test rtreeE-2.1 { COMMIT; } } {} +do_rtree_integrity_test rtreeE-2.1.1 rt2 for {set i 1} {$i<=200} {incr i} { set dx [expr {int(rand()*100)}] diff --git a/ext/rtree/rtreeF.test b/ext/rtree/rtreeF.test index c9620d34f7..561770d085 100644 --- a/ext/rtree/rtreeF.test +++ b/ext/rtree/rtreeF.test @@ -28,6 +28,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { finish_test ; return } @@ -78,4 +79,6 @@ do_execsql_test rtreeF-1.5 { SELECT y FROM t2 ORDER BY y; } {1 4 5 | 1 4} +do_rtree_integrity_test rtreeF-1.6 t3 + finish_test diff --git a/ext/rtree/rtreeG.test b/ext/rtree/rtreeG.test index bffd17ecaa..12225d5832 100644 --- a/ext/rtree/rtreeG.test +++ b/ext/rtree/rtreeG.test @@ -15,6 +15,7 @@ if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } +source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl ifcapable !rtree { finish_test ; return } @@ -37,6 +38,7 @@ do_execsql_test rtreeG-1.2 { INSERT INTO t1 VALUES(1,10,15,5,23),(2,20,21,5,23),(3,10,15,20,30); SELECT id from t1 WHERE x0>8 AND x1<16 AND y0>2 AND y1<25; } {1} +do_rtree_integrity_test rtreeG-1.2.integrity t1 do_test rtreeG-1.2log { set ::log } {} @@ -57,6 +59,7 @@ do_test rtreeG-1.4log { set ::log } {} +expand_all_sql db db close sqlite3_shutdown test_sqlite3_log diff --git a/ext/rtree/rtreeH.test b/ext/rtree/rtreeH.test new file mode 100644 index 0000000000..bff765d530 --- /dev/null +++ b/ext/rtree/rtreeH.test @@ -0,0 +1,80 @@ +# 2018-05-16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file contains tests for the r-tree module, specifically the +# auxiliary column mechanism. + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] rtree_util.tcl] +source $testdir/tester.tcl +ifcapable !rtree { finish_test ; return } + +do_execsql_test rtreeH-100 { + CREATE VIRTUAL TABLE t1 USING rtree(id,x0,x1,y0,y1,+label,+other); + INSERT INTO t1(x0,x1,y0,y1,label) VALUES + (0,10,0,10,'lower-left corner'), + (0,10,90,100,'upper-left corner'), + (90,100,0,10,'lower-right corner'), + (90,100,90,100,'upper-right corner'), + (40,60,40,60,'center'), + (0,5,0,100,'left edge'), + (95,100,0,100,'right edge'), + (0,100,0,5,'bottom edge'), + (0,100,95,100,'top edge'), + (0,100,0,100,'the whole thing'), + (0,50,0,100,'left half'), + (51,100,0,100,'right half'), + (0,100,0,50,'bottom half'), + (0,100,51,100,'top half'); +} {} +do_execsql_test rtreeH-101 { + SELECT * FROM t1_rowid ORDER BY rowid +} {1 1 {lower-left corner} {} 2 1 {upper-left corner} {} 3 1 {lower-right corner} {} 4 1 {upper-right corner} {} 5 1 center {} 6 1 {left edge} {} 7 1 {right edge} {} 8 1 {bottom edge} {} 9 1 {top edge} {} 10 1 {the whole thing} {} 11 1 {left half} {} 12 1 {right half} {} 13 1 {bottom half} {} 14 1 {top half} {}} + +do_execsql_test rtreeH-102 { + SELECT * FROM t1 WHERE rowid=5; +} {5 40.0 60.0 40.0 60.0 center {}} +do_execsql_test rtreeH-103 { + SELECT * FROM t1 WHERE label='center'; +} {5 40.0 60.0 40.0 60.0 center {}} + +do_rtree_integrity_test rtreeH-110 t1 + +do_execsql_test rtreeH-120 { + SELECT label FROM t1 WHERE x1<=50 ORDER BY id +} {{lower-left corner} {upper-left corner} {left edge} {left half}} +do_execsql_test rtreeH-121 { + SELECT label FROM t1 WHERE x1<=50 AND label NOT LIKE '%corner%' ORDER BY id +} {{left edge} {left half}} + +do_execsql_test rtreeH-200 { + WITH RECURSIVE + c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<99), + c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<99) + INSERT INTO t1(id, x0,x1,y0,y1,label) + SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2; +} {} + +do_execsql_test rtreeH-210 { + SELECT label FROM t1 WHERE x0>=48 AND x1<=50 AND y0>=48 AND y1<=50 + ORDER BY id; +} {box-48,48 box-49,48 box-48,49 box-49,49} + +do_execsql_test rtreeH-300 { + UPDATE t1 SET label='x'||label + WHERE x0>=49 AND x1<=50 AND y0>=49 AND y1<=50; + SELECT label FROM t1 WHERE x0>=48 AND x1<=50 AND y0>=48 AND y1<=50 + ORDER BY id; +} {box-48,48 box-49,48 box-48,49 xbox-49,49} + + +finish_test diff --git a/ext/rtree/rtree_util.tcl b/ext/rtree/rtree_util.tcl index 50a1b58065..afa588e4e9 100644 --- a/ext/rtree/rtree_util.tcl +++ b/ext/rtree/rtree_util.tcl @@ -190,3 +190,8 @@ proc rtree_treedump {db zTab} { set d [rtree_depth $db $zTab] rtree_nodetreedump $db $zTab "" $d 1 } + +proc do_rtree_integrity_test {tn tbl} { + uplevel [list do_execsql_test $tn "SELECT rtreecheck('$tbl')" ok] +} + diff --git a/ext/rtree/rtreecheck.test b/ext/rtree/rtreecheck.test new file mode 100644 index 0000000000..cbe8b513c9 --- /dev/null +++ b/ext/rtree/rtreecheck.test @@ -0,0 +1,158 @@ +# 2017 August 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# + + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set testprefix rtreecheck + +ifcapable !rtree { + finish_test + return +} + +proc swap_int32 {blob i0 i1} { + binary scan $blob I* L + + set a [lindex $L $i0] + set b [lindex $L $i1] + + lset L $i0 $b + lset L $i1 $a + + binary format I* $L +} + +proc set_int32 {blob idx val} { + binary scan $blob I* L + lset L $idx $val + binary format I* $L +} + +do_catchsql_test 1.0 { + SELECT rtreecheck(); +} {1 {wrong number of arguments to function rtreecheck()}} + +do_catchsql_test 1.1 { + SELECT rtreecheck(0,0,0); +} {1 {wrong number of arguments to function rtreecheck()}} + + +proc setup_simple_db {{module rtree}} { + reset_db + db func swap_int32 swap_int32 + execsql " + CREATE VIRTUAL TABLE r1 USING $module (id, x1, x2, y1, y2); + INSERT INTO r1 VALUES(1, 5, 5, 5, 5); -- 3 + INSERT INTO r1 VALUES(2, 6, 6, 6, 6); -- 9 + INSERT INTO r1 VALUES(3, 7, 7, 7, 7); -- 15 + INSERT INTO r1 VALUES(4, 8, 8, 8, 8); -- 21 + INSERT INTO r1 VALUES(5, 9, 9, 9, 9); -- 27 + " +} + +setup_simple_db +do_execsql_test 2.1 { + SELECT rtreecheck('r1') +} {ok} + +do_execsql_test 2.2 { + UPDATE r1_node SET data = swap_int32(data, 3, 9); + UPDATE r1_node SET data = swap_int32(data, 23, 29); +} + +do_execsql_test 2.3 { + SELECT rtreecheck('r1') +} {{Dimension 0 of cell 0 on node 1 is corrupt +Dimension 1 of cell 3 on node 1 is corrupt}} + +setup_simple_db +do_execsql_test 2.4 { + DELETE FROM r1_rowid WHERE rowid = 3; + SELECT rtreecheck('r1') +} {{Mapping (3 -> 1) missing from %_rowid table +Wrong number of entries in %_rowid table - expected 5, actual 4}} + +setup_simple_db +do_execsql_test 2.5 { + UPDATE r1_rowid SET nodeno=2 WHERE rowid=3; + SELECT rtreecheck('r1') +} {{Found (3 -> 2) in %_rowid table, expected (3 -> 1)}} + +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE r1 USING rtree_i32(id, x1, x2); + INSERT INTO r1 VALUES(1, 0x7FFFFFFF*-1, 0x7FFFFFFF); + INSERT INTO r1 VALUES(2, 0x7FFFFFFF*-1, 5); + INSERT INTO r1 VALUES(3, -5, 5); + INSERT INTO r1 VALUES(4, 5, 0x11111111); + INSERT INTO r1 VALUES(5, 5, 0x00800000); + INSERT INTO r1 VALUES(6, 5, 0x00008000); + INSERT INTO r1 VALUES(7, 5, 0x00000080); + INSERT INTO r1 VALUES(8, 5, 0x40490fdb); + INSERT INTO r1 VALUES(9, 0x7f800000, 0x7f900000); + SELECT rtreecheck('r1') +} {ok} + +do_execsql_test 3.1 { + CREATE VIRTUAL TABLE r2 USING rtree_i32(id, x1, x2); + INSERT INTO r2 VALUES(2, -1*(1<<31), -1*(1<<31)+5); + SELECT rtreecheck('r2') +} {ok} + +do_execsql_test 3.2 { + BEGIN; + UPDATE r2_node SET data = X'123456'; + SELECT rtreecheck('r2')!="ok"; +} {1} + +do_execsql_test 3.3 { + ROLLBACK; + UPDATE r2_node SET data = X'00001234'; + SELECT rtreecheck('r2')!="ok"; +} {1} + +do_execsql_test 4.0 { + CREATE TABLE notanrtree(i); + SELECT rtreecheck('notanrtree'); +} {{Schema corrupt or not an rtree}} + +#------------------------------------------------------------------------- +# +reset_db +db func set_int32 set_int32 +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE r3 USING rtree_i32(id, x1, x2, y1, y2); + WITH x(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 + ) + INSERT INTO r3 SELECT i, i, i, i, i FROM x; +} +do_execsql_test 5.1 { + BEGIN; + UPDATE r3_node SET data = set_int32(data, 3, 5000); + UPDATE r3_node SET data = set_int32(data, 4, 5000); + SELECT rtreecheck('r3')=='ok' +} 0 +do_execsql_test 5.2 { + ROLLBACK; + BEGIN; + UPDATE r3_node SET data = set_int32(data, 3, 0); + UPDATE r3_node SET data = set_int32(data, 4, 0); + SELECT rtreecheck('r3')=='ok' +} 0 + +finish_test + diff --git a/ext/rtree/rtreeconnect.test b/ext/rtree/rtreeconnect.test new file mode 100644 index 0000000000..16d04d9a04 --- /dev/null +++ b/ext/rtree/rtreeconnect.test @@ -0,0 +1,56 @@ +# 2017 August 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the r-tree extension. Specifically, +# the impact of an SQLITE_SCHEMA error within the rtree module xConnect +# callback. +# + + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set testprefix rtreeconnect + +ifcapable !rtree { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE r1 USING rtree(id, x1, x2, y1, y2); + CREATE TABLE t1(id, x1, x2, y1, y2); + CREATE TABLE log(l); + + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO r1 VALUES(new.id, new.x1, new.x2, new.y1, new.y2); + INSERT INTO log VALUES('r1: ' || new.id); + END; +} + +db close +sqlite3 db test.db +sqlite3 db2 test.db + +do_test 1.1 { + db eval { INSERT INTO log VALUES('startup'); } + db2 eval { CREATE TABLE newtable(x,y); } +} {} + +do_execsql_test 1.2 { + INSERT INTO t1 VALUES(1, 2, 3, 4, 5); +} + +db2 close +db close + +finish_test diff --git a/ext/rtree/util/randomshape.tcl b/ext/rtree/util/randomshape.tcl new file mode 100644 index 0000000000..98725bc9dc --- /dev/null +++ b/ext/rtree/util/randomshape.tcl @@ -0,0 +1,87 @@ +#!/usr/bin/tclsh +# +# This script generates a cluster of random polygons that are useful +# for testing the geopoly extension. +# +# Usage: +# +# tclsh randomshape.tcl | tee x.sql | sqlite3 >x.html +# +# The output files are x.sql and x.html. Run the above multiple times +# until an interesting "x.html" file is found, then use the "x.sql" inputs +# to construct test cases. +# +proc randomenclosure {cx cy p1 p2 p3 p4} { + set r 0 + set pi 3.145926 + set pi2 [expr {$pi*2}] + set x0 [expr {$cx + rand()*$p3 + $p4}] + set ans "\[\[$x0,$cy\]" + while {1} { + set r [expr {$r+$p1+$p2*rand()}] + if {$r>=$pi2} break + set m [expr {rand()*$p3 + $p4}] + set x [expr {$cx+$m*cos($r)}] + set y [expr {$cy+$m*sin($r)}] + append ans ",\[$x,$y\]" + } + append ans ",\[$x0,$cy\]\]" + return $ans +} +proc randomshape1 {} { + set cx [expr {100+int(rand()*800)}] + set cy [expr {100+int(rand()*600)}] + set p1 [expr {rand()*0.1}] + set p2 [expr {rand()*0.5+0.5}] + set p3 [expr {rand()*100+25}] + set p4 [expr {rand()*25}] + return [randomenclosure $cx $cy $p1 $p2 $p3 $p4] +} +proc randomshape1_sm {} { + set cx [expr {100+int(rand()*800)}] + set cy [expr {100+int(rand()*600)}] + set p1 [expr {rand()*0.1}] + set p2 [expr {rand()*0.5+0.5}] + set p3 [expr {rand()*10+25}] + set p4 [expr {rand()*5}] + return [randomenclosure $cx $cy $p1 $p2 $p3 $p4] +} +proc randomshape2 {} { + set cx [expr {400+int(rand()*200)}] + set cy [expr {300+int(rand()*200)}] + set p1 [expr {rand()*0.05}] + set p2 [expr {rand()*0.5+0.5}] + set p3 [expr {rand()*50+200}] + set p4 [expr {rand()*50+100}] + return [randomenclosure $cx $cy $p1 $p2 $p3 $p4] +} +proc randomcolor {} { + set n [expr {int(rand()*5)}] + return [lindex {red orange green blue purple} $n] +} + +puts {.print ''} +puts {.print ''} +puts {CREATE TABLE t1(poly,clr);} +puts {CREATE TABLE t2(poly,clr);} +for {set i 0} {$i<30} {incr i} { + puts "INSERT INTO t1(rowid,poly,clr)" + puts " VALUES($i,'[randomshape1]','[randomcolor]');" +} +for {set i 30} {$i<80} {incr i} { + puts "INSERT INTO t1(rowid,poly,clr)" + puts " VALUES($i,'[randomshape1_sm]','[randomcolor]');" +} +for {set i 100} {$i<105} {incr i} { + puts "INSERT INTO t2(rowid,poly,clr)" + puts " VALUES($i,'[randomshape2]','[randomcolor]');" +} + +puts {DELETE FROM t1 WHERE geopoly_json(poly) IS NULL;} +puts {SELECT geopoly_svg(poly, + printf('style="fill:none;stroke:%s;stroke-width:1;"',clr)) + FROM t1;} +puts {SELECT geopoly_svg(poly, + printf('style="fill:none;stroke:%s;stroke-width:2;"',clr)) + FROM t2;} +puts {.print ''} diff --git a/ext/rtree/visual01.txt b/ext/rtree/visual01.txt new file mode 100644 index 0000000000..281d610842 --- /dev/null +++ b/ext/rtree/visual01.txt @@ -0,0 +1,602 @@ +#!sqlite3 +# +# This is a visual test case for the geopoly virtual table. +# +# Run this script in the sqlite3 CLI, and redirect output into an +# HTML file. This display the HTML in a webbrowser. +# + +/* Test data. +** Lots of shapes to be displayed over a 1000x800 canvas. +*/ +CREATE TEMP TABLE basis(name TEXT, jshape TEXT); +INSERT INTO basis(name,jshape) VALUES + ('box-20','[[0,0],[20,0],[20,20],[0,20],[0,0]]'), + ('house-70','[[0,0],[50,0],[50,50],[25,70],[0,50],[0,0]]'), + ('line-40','[[0,0],[40,0],[40,5],[0,5],[0,0]]'), + ('line-80','[[0,0],[80,0],[80,7],[0,7],[0,0]]'), + ('arrow-50','[[0,0],[25,25],[0,50],[15,25],[0,0]]'), + ('triangle-30','[[0,0],[30,0],[15,30],[0,0]]'), + ('angle-30','[[0,0],[30,0],[30,30],[26,30],[26,4],[0,4],[0,0]]'), + ('star-10','[[1,0],[5,2],[9,0],[7,4],[10,8],[7,7],[5,10],[3,7],[0,8],[3,4],[1,0]]'); +CREATE TEMP TABLE xform(A,B,C,D,clr); +INSERT INTO xform(A,B,clr) VALUES + (1,0,'black'), + (0.707,0.707,'blue'), + (0.5,0.866,'red'), + (-0.866,0.5,'green'); +CREATE TEMP TABLE xyoff(id1,id2,xoff,yoff,PRIMARY KEY(id1,id2,xoff,yoff)) + WITHOUT ROWID; +INSERT INTO xyoff VALUES(1,1,811,659); +INSERT INTO xyoff VALUES(1,1,235,550); +INSERT INTO xyoff VALUES(1,1,481,620); +INSERT INTO xyoff VALUES(1,1,106,494); +INSERT INTO xyoff VALUES(1,1,487,106); +INSERT INTO xyoff VALUES(1,1,817,595); +INSERT INTO xyoff VALUES(1,1,240,504); +INSERT INTO xyoff VALUES(1,1,806,457); +INSERT INTO xyoff VALUES(1,1,608,107); +INSERT INTO xyoff VALUES(1,1,768,662); +INSERT INTO xyoff VALUES(1,2,808,528); +INSERT INTO xyoff VALUES(1,2,768,528); +INSERT INTO xyoff VALUES(1,2,771,171); +INSERT INTO xyoff VALUES(1,2,275,671); +INSERT INTO xyoff VALUES(1,2,326,336); +INSERT INTO xyoff VALUES(1,2,690,688); +INSERT INTO xyoff VALUES(1,2,597,239); +INSERT INTO xyoff VALUES(1,2,317,528); +INSERT INTO xyoff VALUES(1,2,366,223); +INSERT INTO xyoff VALUES(1,2,621,154); +INSERT INTO xyoff VALUES(1,3,829,469); +INSERT INTO xyoff VALUES(1,3,794,322); +INSERT INTO xyoff VALUES(1,3,358,387); +INSERT INTO xyoff VALUES(1,3,184,444); +INSERT INTO xyoff VALUES(1,3,729,500); +INSERT INTO xyoff VALUES(1,3,333,523); +INSERT INTO xyoff VALUES(1,3,117,595); +INSERT INTO xyoff VALUES(1,3,496,201); +INSERT INTO xyoff VALUES(1,3,818,601); +INSERT INTO xyoff VALUES(1,3,541,343); +INSERT INTO xyoff VALUES(1,4,603,248); +INSERT INTO xyoff VALUES(1,4,761,649); +INSERT INTO xyoff VALUES(1,4,611,181); +INSERT INTO xyoff VALUES(1,4,607,233); +INSERT INTO xyoff VALUES(1,4,860,206); +INSERT INTO xyoff VALUES(1,4,310,231); +INSERT INTO xyoff VALUES(1,4,727,539); +INSERT INTO xyoff VALUES(1,4,660,661); +INSERT INTO xyoff VALUES(1,4,403,133); +INSERT INTO xyoff VALUES(1,4,619,331); +INSERT INTO xyoff VALUES(2,1,712,578); +INSERT INTO xyoff VALUES(2,1,567,313); +INSERT INTO xyoff VALUES(2,1,231,423); +INSERT INTO xyoff VALUES(2,1,490,175); +INSERT INTO xyoff VALUES(2,1,898,353); +INSERT INTO xyoff VALUES(2,1,589,483); +INSERT INTO xyoff VALUES(2,1,188,462); +INSERT INTO xyoff VALUES(2,1,720,106); +INSERT INTO xyoff VALUES(2,1,793,380); +INSERT INTO xyoff VALUES(2,1,154,396); +INSERT INTO xyoff VALUES(2,2,324,218); +INSERT INTO xyoff VALUES(2,2,120,327); +INSERT INTO xyoff VALUES(2,2,655,133); +INSERT INTO xyoff VALUES(2,2,516,603); +INSERT INTO xyoff VALUES(2,2,529,572); +INSERT INTO xyoff VALUES(2,2,481,212); +INSERT INTO xyoff VALUES(2,2,802,107); +INSERT INTO xyoff VALUES(2,2,234,509); +INSERT INTO xyoff VALUES(2,2,501,269); +INSERT INTO xyoff VALUES(2,2,349,553); +INSERT INTO xyoff VALUES(2,3,495,685); +INSERT INTO xyoff VALUES(2,3,897,372); +INSERT INTO xyoff VALUES(2,3,350,681); +INSERT INTO xyoff VALUES(2,3,832,257); +INSERT INTO xyoff VALUES(2,3,778,149); +INSERT INTO xyoff VALUES(2,3,683,426); +INSERT INTO xyoff VALUES(2,3,693,217); +INSERT INTO xyoff VALUES(2,3,746,317); +INSERT INTO xyoff VALUES(2,3,805,369); +INSERT INTO xyoff VALUES(2,3,336,585); +INSERT INTO xyoff VALUES(2,4,890,255); +INSERT INTO xyoff VALUES(2,4,556,565); +INSERT INTO xyoff VALUES(2,4,865,555); +INSERT INTO xyoff VALUES(2,4,230,293); +INSERT INTO xyoff VALUES(2,4,247,251); +INSERT INTO xyoff VALUES(2,4,730,563); +INSERT INTO xyoff VALUES(2,4,318,282); +INSERT INTO xyoff VALUES(2,4,220,431); +INSERT INTO xyoff VALUES(2,4,828,336); +INSERT INTO xyoff VALUES(2,4,278,525); +INSERT INTO xyoff VALUES(3,1,324,656); +INSERT INTO xyoff VALUES(3,1,625,362); +INSERT INTO xyoff VALUES(3,1,155,570); +INSERT INTO xyoff VALUES(3,1,267,433); +INSERT INTO xyoff VALUES(3,1,599,121); +INSERT INTO xyoff VALUES(3,1,873,498); +INSERT INTO xyoff VALUES(3,1,789,520); +INSERT INTO xyoff VALUES(3,1,656,378); +INSERT INTO xyoff VALUES(3,1,831,601); +INSERT INTO xyoff VALUES(3,1,256,471); +INSERT INTO xyoff VALUES(3,2,332,258); +INSERT INTO xyoff VALUES(3,2,305,463); +INSERT INTO xyoff VALUES(3,2,796,341); +INSERT INTO xyoff VALUES(3,2,830,229); +INSERT INTO xyoff VALUES(3,2,413,271); +INSERT INTO xyoff VALUES(3,2,269,140); +INSERT INTO xyoff VALUES(3,2,628,441); +INSERT INTO xyoff VALUES(3,2,747,643); +INSERT INTO xyoff VALUES(3,2,584,435); +INSERT INTO xyoff VALUES(3,2,784,314); +INSERT INTO xyoff VALUES(3,3,722,233); +INSERT INTO xyoff VALUES(3,3,815,421); +INSERT INTO xyoff VALUES(3,3,401,267); +INSERT INTO xyoff VALUES(3,3,451,650); +INSERT INTO xyoff VALUES(3,3,329,485); +INSERT INTO xyoff VALUES(3,3,878,370); +INSERT INTO xyoff VALUES(3,3,162,616); +INSERT INTO xyoff VALUES(3,3,844,183); +INSERT INTO xyoff VALUES(3,3,161,216); +INSERT INTO xyoff VALUES(3,3,176,676); +INSERT INTO xyoff VALUES(3,4,780,128); +INSERT INTO xyoff VALUES(3,4,566,121); +INSERT INTO xyoff VALUES(3,4,646,120); +INSERT INTO xyoff VALUES(3,4,223,557); +INSERT INTO xyoff VALUES(3,4,251,117); +INSERT INTO xyoff VALUES(3,4,139,209); +INSERT INTO xyoff VALUES(3,4,813,597); +INSERT INTO xyoff VALUES(3,4,454,538); +INSERT INTO xyoff VALUES(3,4,616,198); +INSERT INTO xyoff VALUES(3,4,210,159); +INSERT INTO xyoff VALUES(4,1,208,415); +INSERT INTO xyoff VALUES(4,1,326,665); +INSERT INTO xyoff VALUES(4,1,612,133); +INSERT INTO xyoff VALUES(4,1,537,513); +INSERT INTO xyoff VALUES(4,1,638,438); +INSERT INTO xyoff VALUES(4,1,808,269); +INSERT INTO xyoff VALUES(4,1,552,121); +INSERT INTO xyoff VALUES(4,1,100,189); +INSERT INTO xyoff VALUES(4,1,643,664); +INSERT INTO xyoff VALUES(4,1,726,378); +INSERT INTO xyoff VALUES(4,2,478,409); +INSERT INTO xyoff VALUES(4,2,497,507); +INSERT INTO xyoff VALUES(4,2,233,148); +INSERT INTO xyoff VALUES(4,2,587,237); +INSERT INTO xyoff VALUES(4,2,604,166); +INSERT INTO xyoff VALUES(4,2,165,455); +INSERT INTO xyoff VALUES(4,2,320,258); +INSERT INTO xyoff VALUES(4,2,353,496); +INSERT INTO xyoff VALUES(4,2,347,495); +INSERT INTO xyoff VALUES(4,2,166,622); +INSERT INTO xyoff VALUES(4,3,461,332); +INSERT INTO xyoff VALUES(4,3,685,278); +INSERT INTO xyoff VALUES(4,3,427,594); +INSERT INTO xyoff VALUES(4,3,467,346); +INSERT INTO xyoff VALUES(4,3,125,548); +INSERT INTO xyoff VALUES(4,3,597,680); +INSERT INTO xyoff VALUES(4,3,820,445); +INSERT INTO xyoff VALUES(4,3,144,330); +INSERT INTO xyoff VALUES(4,3,557,434); +INSERT INTO xyoff VALUES(4,3,254,315); +INSERT INTO xyoff VALUES(4,4,157,339); +INSERT INTO xyoff VALUES(4,4,249,220); +INSERT INTO xyoff VALUES(4,4,391,323); +INSERT INTO xyoff VALUES(4,4,589,429); +INSERT INTO xyoff VALUES(4,4,859,592); +INSERT INTO xyoff VALUES(4,4,337,680); +INSERT INTO xyoff VALUES(4,4,410,288); +INSERT INTO xyoff VALUES(4,4,636,596); +INSERT INTO xyoff VALUES(4,4,734,433); +INSERT INTO xyoff VALUES(4,4,559,549); +INSERT INTO xyoff VALUES(5,1,549,607); +INSERT INTO xyoff VALUES(5,1,584,498); +INSERT INTO xyoff VALUES(5,1,699,116); +INSERT INTO xyoff VALUES(5,1,525,524); +INSERT INTO xyoff VALUES(5,1,304,667); +INSERT INTO xyoff VALUES(5,1,302,232); +INSERT INTO xyoff VALUES(5,1,403,149); +INSERT INTO xyoff VALUES(5,1,824,403); +INSERT INTO xyoff VALUES(5,1,697,203); +INSERT INTO xyoff VALUES(5,1,293,689); +INSERT INTO xyoff VALUES(5,2,199,275); +INSERT INTO xyoff VALUES(5,2,395,393); +INSERT INTO xyoff VALUES(5,2,657,642); +INSERT INTO xyoff VALUES(5,2,200,655); +INSERT INTO xyoff VALUES(5,2,882,234); +INSERT INTO xyoff VALUES(5,2,483,565); +INSERT INTO xyoff VALUES(5,2,755,640); +INSERT INTO xyoff VALUES(5,2,810,305); +INSERT INTO xyoff VALUES(5,2,731,655); +INSERT INTO xyoff VALUES(5,2,466,690); +INSERT INTO xyoff VALUES(5,3,563,584); +INSERT INTO xyoff VALUES(5,3,491,117); +INSERT INTO xyoff VALUES(5,3,779,292); +INSERT INTO xyoff VALUES(5,3,375,637); +INSERT INTO xyoff VALUES(5,3,253,553); +INSERT INTO xyoff VALUES(5,3,797,514); +INSERT INTO xyoff VALUES(5,3,229,480); +INSERT INTO xyoff VALUES(5,3,257,194); +INSERT INTO xyoff VALUES(5,3,449,555); +INSERT INTO xyoff VALUES(5,3,849,630); +INSERT INTO xyoff VALUES(5,4,329,286); +INSERT INTO xyoff VALUES(5,4,640,197); +INSERT INTO xyoff VALUES(5,4,104,150); +INSERT INTO xyoff VALUES(5,4,438,272); +INSERT INTO xyoff VALUES(5,4,773,226); +INSERT INTO xyoff VALUES(5,4,441,650); +INSERT INTO xyoff VALUES(5,4,242,340); +INSERT INTO xyoff VALUES(5,4,301,435); +INSERT INTO xyoff VALUES(5,4,171,397); +INSERT INTO xyoff VALUES(5,4,541,619); +INSERT INTO xyoff VALUES(6,1,651,301); +INSERT INTO xyoff VALUES(6,1,637,137); +INSERT INTO xyoff VALUES(6,1,765,643); +INSERT INTO xyoff VALUES(6,1,173,296); +INSERT INTO xyoff VALUES(6,1,263,192); +INSERT INTO xyoff VALUES(6,1,791,302); +INSERT INTO xyoff VALUES(6,1,860,601); +INSERT INTO xyoff VALUES(6,1,780,445); +INSERT INTO xyoff VALUES(6,1,462,214); +INSERT INTO xyoff VALUES(6,1,802,207); +INSERT INTO xyoff VALUES(6,2,811,685); +INSERT INTO xyoff VALUES(6,2,533,531); +INSERT INTO xyoff VALUES(6,2,390,614); +INSERT INTO xyoff VALUES(6,2,260,580); +INSERT INTO xyoff VALUES(6,2,116,377); +INSERT INTO xyoff VALUES(6,2,860,458); +INSERT INTO xyoff VALUES(6,2,438,590); +INSERT INTO xyoff VALUES(6,2,604,562); +INSERT INTO xyoff VALUES(6,2,241,242); +INSERT INTO xyoff VALUES(6,2,667,298); +INSERT INTO xyoff VALUES(6,3,787,698); +INSERT INTO xyoff VALUES(6,3,868,521); +INSERT INTO xyoff VALUES(6,3,412,587); +INSERT INTO xyoff VALUES(6,3,640,131); +INSERT INTO xyoff VALUES(6,3,748,410); +INSERT INTO xyoff VALUES(6,3,257,244); +INSERT INTO xyoff VALUES(6,3,411,195); +INSERT INTO xyoff VALUES(6,3,464,356); +INSERT INTO xyoff VALUES(6,3,157,339); +INSERT INTO xyoff VALUES(6,3,434,505); +INSERT INTO xyoff VALUES(6,4,480,671); +INSERT INTO xyoff VALUES(6,4,519,228); +INSERT INTO xyoff VALUES(6,4,404,513); +INSERT INTO xyoff VALUES(6,4,120,538); +INSERT INTO xyoff VALUES(6,4,403,663); +INSERT INTO xyoff VALUES(6,4,477,677); +INSERT INTO xyoff VALUES(6,4,690,154); +INSERT INTO xyoff VALUES(6,4,606,498); +INSERT INTO xyoff VALUES(6,4,430,665); +INSERT INTO xyoff VALUES(6,4,499,273); +INSERT INTO xyoff VALUES(7,1,118,526); +INSERT INTO xyoff VALUES(7,1,817,522); +INSERT INTO xyoff VALUES(7,1,388,638); +INSERT INTO xyoff VALUES(7,1,181,265); +INSERT INTO xyoff VALUES(7,1,442,332); +INSERT INTO xyoff VALUES(7,1,475,282); +INSERT INTO xyoff VALUES(7,1,722,633); +INSERT INTO xyoff VALUES(7,1,104,394); +INSERT INTO xyoff VALUES(7,1,631,262); +INSERT INTO xyoff VALUES(7,1,372,392); +INSERT INTO xyoff VALUES(7,2,600,413); +INSERT INTO xyoff VALUES(7,2,386,223); +INSERT INTO xyoff VALUES(7,2,839,174); +INSERT INTO xyoff VALUES(7,2,293,410); +INSERT INTO xyoff VALUES(7,2,281,391); +INSERT INTO xyoff VALUES(7,2,859,387); +INSERT INTO xyoff VALUES(7,2,478,347); +INSERT INTO xyoff VALUES(7,2,646,690); +INSERT INTO xyoff VALUES(7,2,713,234); +INSERT INTO xyoff VALUES(7,2,199,588); +INSERT INTO xyoff VALUES(7,3,389,256); +INSERT INTO xyoff VALUES(7,3,349,542); +INSERT INTO xyoff VALUES(7,3,363,345); +INSERT INTO xyoff VALUES(7,3,751,302); +INSERT INTO xyoff VALUES(7,3,423,386); +INSERT INTO xyoff VALUES(7,3,267,444); +INSERT INTO xyoff VALUES(7,3,243,182); +INSERT INTO xyoff VALUES(7,3,453,658); +INSERT INTO xyoff VALUES(7,3,126,345); +INSERT INTO xyoff VALUES(7,3,120,472); +INSERT INTO xyoff VALUES(7,4,359,654); +INSERT INTO xyoff VALUES(7,4,339,516); +INSERT INTO xyoff VALUES(7,4,710,452); +INSERT INTO xyoff VALUES(7,4,810,560); +INSERT INTO xyoff VALUES(7,4,644,692); +INSERT INTO xyoff VALUES(7,4,826,327); +INSERT INTO xyoff VALUES(7,4,465,462); +INSERT INTO xyoff VALUES(7,4,310,456); +INSERT INTO xyoff VALUES(7,4,577,613); +INSERT INTO xyoff VALUES(7,4,502,555); +INSERT INTO xyoff VALUES(8,1,601,620); +INSERT INTO xyoff VALUES(8,1,372,683); +INSERT INTO xyoff VALUES(8,1,758,399); +INSERT INTO xyoff VALUES(8,1,485,552); +INSERT INTO xyoff VALUES(8,1,159,563); +INSERT INTO xyoff VALUES(8,1,536,303); +INSERT INTO xyoff VALUES(8,1,122,263); +INSERT INTO xyoff VALUES(8,1,836,435); +INSERT INTO xyoff VALUES(8,1,544,146); +INSERT INTO xyoff VALUES(8,1,270,277); +INSERT INTO xyoff VALUES(8,2,849,281); +INSERT INTO xyoff VALUES(8,2,563,242); +INSERT INTO xyoff VALUES(8,2,704,463); +INSERT INTO xyoff VALUES(8,2,102,165); +INSERT INTO xyoff VALUES(8,2,797,524); +INSERT INTO xyoff VALUES(8,2,612,426); +INSERT INTO xyoff VALUES(8,2,345,372); +INSERT INTO xyoff VALUES(8,2,820,376); +INSERT INTO xyoff VALUES(8,2,789,156); +INSERT INTO xyoff VALUES(8,2,321,466); +INSERT INTO xyoff VALUES(8,3,150,332); +INSERT INTO xyoff VALUES(8,3,136,152); +INSERT INTO xyoff VALUES(8,3,468,528); +INSERT INTO xyoff VALUES(8,3,409,192); +INSERT INTO xyoff VALUES(8,3,820,216); +INSERT INTO xyoff VALUES(8,3,847,249); +INSERT INTO xyoff VALUES(8,3,801,267); +INSERT INTO xyoff VALUES(8,3,181,670); +INSERT INTO xyoff VALUES(8,3,398,563); +INSERT INTO xyoff VALUES(8,3,439,576); +INSERT INTO xyoff VALUES(8,4,123,309); +INSERT INTO xyoff VALUES(8,4,190,496); +INSERT INTO xyoff VALUES(8,4,571,531); +INSERT INTO xyoff VALUES(8,4,290,255); +INSERT INTO xyoff VALUES(8,4,244,412); +INSERT INTO xyoff VALUES(8,4,264,596); +INSERT INTO xyoff VALUES(8,4,253,420); +INSERT INTO xyoff VALUES(8,4,847,536); +INSERT INTO xyoff VALUES(8,4,120,288); +INSERT INTO xyoff VALUES(8,4,331,639); + +/* Create the geopoly object from test data above */ +CREATE VIRTUAL TABLE geo1 USING geopoly(type,clr); +INSERT INTO geo1(_shape,type,clr) + SELECT geopoly_xform(jshape,A,B,-B,A,xoff,yoff), basis.name, xform.clr + FROM basis, xform, xyoff + WHERE xyoff.id1=basis.rowid AND xyoff.id2=xform.rowid; + + +/* Query polygon */ +CREATE TEMP TABLE querypoly(poly JSON, clr TEXT); +INSERT INTO querypoly(clr, poly) VALUES + ('orange', '[[300,300],[400,350],[500,250],[480,500],[400,480],[300,550],[280,450],[320,400],[280,350],[300,300]]'); + +/* Generate the HTML */ +.print '' +.print '

Everything

' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',clr) + ) + FROM geo1; +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +.print '' + +.print '

Overlap Query

' +.print '
'
+.print 'SELECT *'
+.print '  FROM geo1, querypoly'
+.print ' WHERE geopoly_overlap(_shape, poly);'
+.print 
+EXPLAIN QUERY PLAN
+SELECT geopoly_svg(_shape,
+         printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
+       )
+  FROM geo1, querypoly
+ WHERE geopoly_overlap(_shape, poly);
+.print '
' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1, querypoly + WHERE geopoly_overlap(_shape, poly); +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +.print '' + +.print '

Overlap Query And Result Bounding Box

' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1, querypoly + WHERE geopoly_overlap(_shape, poly); +SELECT geopoly_svg(geopoly_bbox(poly), + 'style="fill:none;stroke:black;stroke-width:3"' + ) + FROM querypoly; +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +SELECT geopoly_svg(geopoly_group_bbox(_shape), + 'style="fill:none;stroke:red;stroke-width:3"' + ) + FROM geo1, querypoly + WHERE geopoly_overlap(_shape, poly); +.print '' + +.print '

Bounding-Box Overlap Query

' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ), + geopoly_svg(geopoly_bbox(_shape), + 'style="fill:none;stroke:black;stroke-width:1"' + ) + FROM geo1, querypoly + WHERE geopoly_overlap(geopoly_bbox(_shape), geopoly_bbox(poly)); +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +SELECT geopoly_svg(geopoly_bbox(poly), + 'style="fill:none;stroke:black;stroke-width:3"' + ) + FROM querypoly; +.print '' + +.print '

Within Query

' +.print '
'
+.print 'SELECT *'
+.print '  FROM geo1, querypoly'
+.print ' WHERE geopoly_within(_shape, poly);'
+.print 
+EXPLAIN QUERY PLAN
+SELECT geopoly_svg(_shape,
+         printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
+       )
+  FROM geo1, querypoly
+ WHERE geopoly_within(_shape, poly);
+.print '
' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1, querypoly + WHERE geopoly_within(_shape, poly); +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +.print '' + +.print '

Bounding-Box WITHIN Query

' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ), + geopoly_svg(geopoly_bbox(_shape), + 'style="fill:none;stroke:black;stroke-width:1"' + ) + FROM geo1, querypoly + WHERE geopoly_within(geopoly_bbox(_shape), geopoly_bbox(poly)); +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +SELECT geopoly_svg(geopoly_bbox(poly), + 'style="fill:none;stroke:black;stroke-width:3"' + ) + FROM querypoly; +.print '' + +.print '

Not Overlap Query

' +.print '
'
+.print 'SELECT *'
+.print '  FROM geo1, querypoly'
+.print ' WHERE NOT geopoly_overlap(_shape, poly);'
+.print 
+EXPLAIN QUERY PLAN
+SELECT geopoly_svg(_shape,
+         printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
+       )
+  FROM geo1, querypoly
+ WHERE NOT geopoly_overlap(_shape, poly);
+.print '
' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1, querypoly + WHERE NOT geopoly_overlap(_shape, poly); +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +.print '' + +.print '

Not Within Query

' +.print '
'
+.print 'SELECT *'
+.print '  FROM geo1, querypoly'
+.print ' WHERE NOT geopoly_within(_shape, poly);'
+.print 
+EXPLAIN QUERY PLAN
+SELECT geopoly_svg(_shape,
+         printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr)
+       )
+  FROM geo1, querypoly
+ WHERE NOT geopoly_within(_shape, poly);
+.print '
' +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1, querypoly + WHERE NOT geopoly_within(_shape, poly); +SELECT geopoly_svg(poly, + printf('style="fill:%s;fill-opacity:0.5;"',clr) + ) + FROM querypoly; +.print '' + +.print '

Color-Change For Overlapping Elements

' +BEGIN; +UPDATE geo1 + SET clr=CASE WHEN rowid IN (SELECT geo1.rowid FROM geo1, querypoly + WHERE geopoly_overlap(_shape,poly)) + THEN 'red' ELSE 'blue' END; +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1; +SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"') + FROM querypoly; +ROLLBACK; +.print '' + +.print '

Color-Change And Move Overlapping Elements

' +BEGIN; +UPDATE geo1 + SET clr=CASE WHEN rowid IN (SELECT geo1.rowid FROM geo1, querypoly + WHERE geopoly_overlap(_shape,poly)) + THEN 'red' ELSE '#76ccff' END; +UPDATE geo1 + SET _shape=geopoly_xform(_shape,1,0,0,1,300,0) + WHERE geopoly_overlap(_shape,(SELECT poly FROM querypoly)); +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1; +SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"') + FROM querypoly; +--ROLLBACK; +.print '' + + +.print '

Overlap With Translated Query Polygon

' +UPDATE querypoly SET poly=geopoly_xform(poly,1,0,0,1,300,0); +.print '' +SELECT geopoly_svg(_shape, + printf('style="fill:none;stroke:%s;stroke-width:1"',geo1.clr) + ) + FROM geo1 + WHERE geopoly_overlap(_shape,(SELECT poly FROM querypoly)); +SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"') + FROM querypoly; +ROLLBACK; +.print '' + +.print '

Regular Polygons

' +.print '' +SELECT geopoly_svg(geopoly_regular(100,100,40,3),'style="fill:none;stroke:red;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(200,100,40,4),'style="fill:none;stroke:orange;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(300,100,40,5),'style="fill:none;stroke:green;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(400,100,40,6),'style="fill:none;stroke:blue;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(500,100,40,7),'style="fill:none;stroke:purple;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(600,100,40,8),'style="fill:none;stroke:red;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(700,100,40,10),'style="fill:none;stroke:orange;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(800,100,40,20),'style="fill:none;stroke:green;stroke-width:1"'); +SELECT geopoly_svg(geopoly_regular(900,100,40,30),'style="fill:none;stroke:blue;stroke-width:1"'); +.print '' + +.print '' diff --git a/ext/session/session1.test b/ext/session/session1.test index 9e3fc4b87a..f423a0cf4b 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -612,6 +612,49 @@ do_iterator_test $tn.12.2 * { {UPDATE t1 0 X.. {i 3 {} {} i 3} {{} {} {} {} t one}} } +#------------------------------------------------------------------------- +# Test that no savepoint is used if -nosavepoint is specified. +# +do_execsql_test $tn.13.1 { + CREATE TABLE x1(a INTEGER PRIMARY KEY, b)%WR%; +} +do_test $tn.13.2 { + execsql BEGIN + set C [changeset_from_sql { + INSERT INTO x1 VALUES(1, 'one'); + INSERT INTO x1 VALUES(2, 'two'); + INSERT INTO x1 VALUES(3, 'three'); + }] + execsql ROLLBACK + execsql { + INSERT INTO x1 VALUES(1, 'i'); + INSERT INTO x1 VALUES(2, 'ii'); + INSERT INTO x1 VALUES(3, 'iii'); + } +} {} + +proc xConflict {args} { + set ret [lindex $::CONFLICT_HANDLERS 0] + set ::CONFLICT_HANDLERS [lrange $::CONFLICT_HANDLERS 1 end] + set ret +} +do_test $tn.13.3 { + set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] + execsql BEGIN + catch { sqlite3changeset_apply_v2 db $C xConflict } msg + execsql { + SELECT * FROM x1 + } +} {1 i 2 ii 3 iii} +do_test $tn.13.3 { + set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] + execsql ROLLBACK + execsql BEGIN + catch { sqlite3changeset_apply_v2 -nosavepoint db $C xConflict } msg + execsql { SELECT * FROM x1 } +} {1 one 2 two 3 iii} +execsql ROLLBACK + }] } diff --git a/ext/session/session4.test b/ext/session/session4.test index 120a230b57..de183a69a0 100644 --- a/ext/session/session4.test +++ b/ext/session/session4.test @@ -11,6 +11,8 @@ # This file implements regression tests for the session module. # +package require Tcl 8.6 + if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } @@ -64,4 +66,81 @@ do_test 1.3 { list [catch { sqlite3changeset_apply db $x xConflict } msg] $msg } {1 SQLITE_CORRUPT} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d); + CREATE TABLE t2(e TEXT PRIMARY KEY NOT NULL,f,g); + CREATE TABLE t3(w REAL PRIMARY KEY NOT NULL,x,y); + CREATE TABLE t4(z PRIMARY KEY) WITHOUT ROWID; +} + +foreach {tn blob} { + 1 54010174340012000000 + 2 54fefe8bcb0012000300 + 3 5480809280808001017434001200fb + 4 50af9c939c9c9cb09c9c6400b09c9c6400 + 5 12000300 + 6 09847304 + 7 5401017434001208 + 8 54010174340012fc0386868600 + 9 54010174340012FC0386868600 + 10 548894FEFE + 11 54010171340012E703ABFA7433FD1200 + 12 540101743400120003FFED00010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572 + 13 540101743400120003001200010000000000000002120002400C0000000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FC87797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572 + 14 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F03FC87797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572 + 15 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003FC8738790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572 + 16 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A00540301000074320009000303783879010000000080000000020000000000000000090003FC87327902400C0000000000000304666F7572 + 17 540101743400120003FFE3000412F7010000E600000000021202120002400C0000000000005B0401000000743100171C0304646F750002400C000000000000540401000000D3310017000100000000000000050100000000000378797A405403000002F10100000100000000000004090001000100000007030378797A0100000000000D0007000001000000002300000F1B0378797A405403013900743200090003038C3879010000000000000000000002120002400C0000000000005B0401000000743117170003047C5E00FF + 18 54010174340012000300120001000000E6FF100000120002401E00000000000054040100000074310017000100040000010000000000000004FFFF7FFF0000000000010000010000001000000007030378797A01000000000000000F000000000000FA0304666F7572 + 19 540101743400120003001200010000000000000002121B02400C00000000000054040000000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378817A01000000000000000F000001000000000100000F030378797A005403010000743200090003FFE809000303780000000000000304666F7572 + 20 5401017D3400120003001200010000000000000002120002400CFC00000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FFFF797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378326C02400C0000000000000304666F7572 + 21 5401017434001200030012000100FFE20000000002120002400C00000000000054040100E0007431001700010000E99D000000020000000003FFE70009000303783279020004000001030000000000002117000003001700012701000100000000743100000100000000008000090003037F387901000000008000000002000000000400000009005303010A00FF7FFFFF00000000000304664F6572 + 22 540101743400120003FFFF7FFF0000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100010000000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572 + 23 540101742700120100120003F5FF0300 + 24 5401017434E312540101743400120003FFFC00 + 25 540101743400540101743D3D3D3D3D3D3D3D3D3D3D3D3D3400120003FFED000300 + 26 5401017446EA5301743D1D3D3D01743D1D3D3DCF3D3D3D1A3D3D3D3D3400120003FFFF000000 + 27 540101743400540101743D3D3D3D3D3D3D3D3D3D251000120003FF81000000000000 + 28 540101340012000397FF3D7F3D3400120003001200540101743D3D3D3D3D3D393D3D3D12000300 + 29 500174340050010F74340012000300120003FFE5 + 30 5004007233E900177FEF0054257F0002EF001200031E12000300 + 31 5001015001015252525250010174340012EF039A9A0100E351525D52525252525252525252525252525252525250010174340012EF039A0100009A9A9A9A9A9BA3B200120003010040743400 + 32 5401017400123400120003FFFC00 + 33 540101743400120003001200010000000000004002120002400C0000000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FC87797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572 + 34 54040100000074310017000100000002000015050100000000000000030100000000140000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A0054030100007432000900030378387901000000008E000000020000000000000000090003FFFF000002400C0000000000000304666F7572 + 35 540101743400120003001200010000000000000002120002400C00000000000050060100000074310017000100000000000000050100000000000000030100000003001700010000666F7572 + 36 540101743400120003001200010000000000000002120002400C00000000000050050100000074310017000100000000000000050100000000000000030100000003001700010000666F7572 + 37 540101743400120003001200010000000000000002120002400C00000000000050040100008074310017000100000000000000050100000000000000030100000003001700010000666F7572 + 38 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000000000000000000050100000000000000030100000003001700010000666F7572 + 39 540101743400120003001200010000000000000002120002400C00000000000050040100018074310017000100000000000000050100000000000000030100000003001700010000666F7572 + 40 540101743400120003001200010000000000000002120002400C0000000000005004FEFFFFFF74310017000100000000000000050100000000000000030100000003001700010000666F7572 + 41 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000004000000000000050100000000000000030100000003001700010000666F7572 + 42 540101743400120003001200010000000000000002120002400C0000000000005005FFFF050074310017000100000000000000050100000000000000030100000003001700010000666F7572 + 43 540101743400120003001200010000000000000002120002400C000000000000500401006E0074310017000300000000001221050100000000000000030100000003001700010000666F7572 + 44 540101743400120003001200010000000000020000120002400C00000000000050050100000074310017000100000000000000050100004000000000030100000025001700010000666F7572 + 45 540101743400120003001200010000000000ECFF02120002400C000000000000500401F9FF00743100170001000000000000000500E1000000000000030100000003000000000000666F7572 + 46 54010174340B0B0B0B0B0B0B0B0B0B0B0B0B0B0B00120003001200010000000000000002120002400C00000000000050040100000074310017010000000000000000050100FFE900000000030100000003007F00000000666F7572 + 47 54010103001200010000000000020002120002400C0000000000005004010000F374310017000100000000000000050100000000000000030100000003001700010000666F8E72 + 48 540101743400120003001200010000000000000002120002400C00000000000050030012000174310017000700000000000000050100002000000001000000000003001700010000666F7572 + 49 540101743400120004001200010000000000000002120002400C0000000000005004010000FC733100170001000000000000000501000000000000000301000000F6FF17000100007C6F7572 + 50 54010174FFDDFF8003001200010000100000000002120002400C000000000000500401000000743100170000000005010000000000000000000003010072 + 51 540101743200120003001200010000000000000002120002400C00000000000050040100001074310017000000000003010000120300170100000000000000050100000000000000030100000003001700010000666F7572 + 52 540101745401017434001200010000000000001702120002400C00000000000050040100001A74310017000100000000000100000100000000000000030100000003001700010000666F7572 + 53 540101743400120003001200010000000000000002120002400C000000000000500401000000743100170001000002400C00000000000050040110000074310017000000000000050100000000000000030100000003001700010000666F7572 + 54 540101743400120003001200010000000000000002120002400C000000000002120002400C00000000000050040100000074310017FF0050040100000074310017FF7F00000000000000050100000000000000030100000003001700010000666F7572 + 55 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000100010080000001000000020003010100000300170100000003001700010000666F7572 + 56 5487ffffff7f +} { + do_test 2.$tn { + set changeset [binary decode hex $blob] +#set fd [open x.change w+] +#fconfigure $fd -encoding binary -translation binary +#puts -nonewline $fd $changeset +#close $fd + list [catch { sqlite3changeset_apply db $changeset xConflict } msg] $msg + } {1 SQLITE_CORRUPT} +} + finish_test diff --git a/ext/session/sessionD.test b/ext/session/sessionD.test index b8572782e2..84c31cbc2f 100644 --- a/ext/session/sessionD.test +++ b/ext/session/sessionD.test @@ -221,5 +221,38 @@ do_test 4.2.2 { } {1 {SQLITE_SCHEMA - table schemas do not match}} S delete +do_test 4.3.1 { + sqlite3session S db main + S attach t4 + execsql { CREATE TABLE t4(i PRIMARY KEY, b) } + list [catch { S diff ixua t4 } msg] $msg +} {1 {SQLITE_SCHEMA - table schemas do not match}} +S delete +do_catchsql_test 4.3.2 { + SELECT * FROM ixua.t4; +} {1 {no such table: ixua.t4}} + +do_test 4.4.1 { + sqlite3session S db main + S attach sqlite_stat1 + execsql { ANALYZE } + execsql { DROP TABLE ixua.sqlite_stat1 } + list [catch { S diff ixua sqlite_stat1 } msg] $msg +} {1 {SQLITE_SCHEMA - table schemas do not match}} +S delete +do_catchsql_test 4.4.2 { + SELECT * FROM ixua.sqlite_stat1; +} {1 {no such table: ixua.sqlite_stat1}} + +do_test 4.5.1 { + sqlite3session S db main + S attach t8 + list [catch { S diff ixua t8 } msg] $msg +} {0 {}} +S delete +do_catchsql_test 4.5.2 { + SELECT * FROM ixua.i8; +} {1 {no such table: ixua.i8}} + finish_test diff --git a/ext/session/sessionG.test b/ext/session/sessionG.test index 5c057350e4..1b5f5473f0 100644 --- a/ext/session/sessionG.test +++ b/ext/session/sessionG.test @@ -173,5 +173,79 @@ do_test 4.3 { compare_db db db2 } {} +#------------------------------------------------------------------------- +reset_db +catch { db2 close } +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_execsql_test 5.0.1 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE TABLE t2(a, b, c PRIMARY KEY); + CREATE TABLE t3(a, b PRIMARY KEY, c); +} +do_execsql_test -db db2 5.0.2 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE TABLE t2(a, b, c); + CREATE TABLE t3(a, b PRIMARY KEY, c); +} + +do_test 5.1 { + do_then_apply_sql { + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t2 VALUES(4, 5, 6); + INSERT INTO t3 VALUES(7, 8, 9); + } + + db2 eval { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 2 3 7 8 9} + +#------------------------------------------------------------------------- + +reset_db +db func number_name number_name +do_execsql_test 6.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE UNIQUE INDEX t1b ON t1(b); + WITH s(i) AS ( + SELECT 1 + UNION ALL + SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO t1 SELECT i, number_name(i) FROM s; +} + +do_test 6.1 { + db eval BEGIN + set ::C [changeset_from_sql { + DELETE FROM t1; + WITH s(i) AS ( + SELECT 1 + UNION ALL + SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO t1 SELECT i, number_name(i+1) FROM s; + }] + db eval ROLLBACK + execsql { SELECT count(*) FROM t1 WHERE number_name(a) IS NOT b } +} {0} + +proc xConflict {args} { exit ; return "OMIT" } +do_test 6.2 { + sqlite3changeset_apply db $C xConflict +} {} + +do_execsql_test 6.3 { SELECT count(*) FROM t1; } {1000} +do_execsql_test 6.4 { + SELECT count(*) FROM t1 WHERE number_name(a+1) IS NOT b; +} {0} + +# db eval { SELECT * FROM t1 } { puts "$a || $b" } + + finish_test diff --git a/ext/session/sessionH.test b/ext/session/sessionH.test new file mode 100644 index 0000000000..643fdb3fbe --- /dev/null +++ b/ext/session/sessionH.test @@ -0,0 +1,39 @@ +# 2018 January 18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix sessionH + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 1.0 { + do_common_sql { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)); + } + do_then_apply_sql { + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERe i<10000 + ) + INSERT INTO t1 SELECT 'abcde', randomblob(16), i FROM s; + } + compare_db db db2 +} {} + + +finish_test + diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index d4804d924f..543b970327 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -169,3 +169,30 @@ proc changeset_to_list {c} { sqlite3session_foreach elem $c { lappend list $elem } lsort $list } + +set ones {zero one two three four five six seven eight nine + ten eleven twelve thirteen fourteen fifteen sixteen seventeen + eighteen nineteen} +set tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety} +proc number_name {n} { + if {$n>=1000} { + set txt "[number_name [expr {$n/1000}]] thousand" + set n [expr {$n%1000}] + } else { + set txt {} + } + if {$n>=100} { + append txt " [lindex $::ones [expr {$n/100}]] hundred" + set n [expr {$n%100}] + } + if {$n>=20} { + append txt " [lindex $::tens [expr {$n/10}]]" + set n [expr {$n%10}] + } + if {$n>0} { + append txt " [lindex $::ones $n]" + } + set txt [string trim $txt] + if {$txt==""} {set txt zero} + return $txt +} diff --git a/ext/session/sessionat.test b/ext/session/sessionat.test index f482d01520..4a3f59a441 100644 --- a/ext/session/sessionat.test +++ b/ext/session/sessionat.test @@ -241,5 +241,9 @@ eval [string map [list %WR% $trailing] { }] } +catch { db close } +catch { db2 close } +sqlite3_shutdown +test_sqlite3_log finish_test diff --git a/ext/session/sessionfault2.test b/ext/session/sessionfault2.test index ffdc57b9bc..fb848e1935 100644 --- a/ext/session/sessionfault2.test +++ b/ext/session/sessionfault2.test @@ -20,6 +20,8 @@ source $testdir/tester.tcl ifcapable !session {finish_test; return} set testprefix sessionfault2 +if 1 { + do_execsql_test 1.0.0 { CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); INSERT INTO t1 VALUES(1, 1); @@ -103,5 +105,181 @@ do_faultsim_test 2 -faults oom-p* -prep { faultsim_integrity_check } +#------------------------------------------------------------------------- +# OOM when collecting and apply a changeset that uses sqlite_stat1. +# +reset_db +forcedelete test.db2 +sqlite3 db2 test.db2 +do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c); + CREATE INDEX i1 ON t1(c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); + CREATE TABLE t2(a, b, c); + INSERT INTO t2 VALUES(1, 2, 3); + INSERT INTO t2 VALUES(4, 5, 6); + INSERT INTO t2 VALUES(7, 8, 9); + ANALYZE; +} +faultsim_save_and_close +db2 close + +do_faultsim_test 1.1 -faults oom-* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + sqlite3 db2 test.db2 +} -body { + do_then_apply_sql { + INSERT INTO sqlite_stat1 VALUES('x', 'y', 45); + UPDATE sqlite_stat1 SET stat = 123 WHERE tbl='t1' AND idx='i1'; + UPDATE sqlite_stat1 SET stat = 456 WHERE tbl='t2'; + } +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + faultsim_integrity_check + if {$testrc==0} { compare_db db db2 } +} + +#------------------------------------------------------------------------- +# OOM when collecting and using a rebase changeset. +# +reset_db +do_execsql_test 2.0 { + CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c)); + CREATE TABLE t4(x PRIMARY KEY, y, z); + + INSERT INTO t3 VALUES(1, 2, 3); + INSERT INTO t3 VALUES(4, 2, 5); + INSERT INTO t3 VALUES(7, 2, 9); + + INSERT INTO t4 VALUES('a', 'b', 'c'); + INSERT INTO t4 VALUES('d', 'e', 'f'); + INSERT INTO t4 VALUES('g', 'h', 'i'); +} +faultsim_save_and_close +db2 close + +proc xConflict {ret args} { return $ret } + +do_test 2.1 { + faultsim_restore_and_reopen + set C1 [changeset_from_sql { + INSERT INTO t3 VALUES(10, 11, 12); + UPDATE t4 SET y='j' WHERE x='g'; + DELETE FROM t4 WHERE x='a'; + }] + + faultsim_restore_and_reopen + set C2 [changeset_from_sql { + INSERT INTO t3 VALUES(1000, 11, 12); + DELETE FROM t4 WHERE x='g'; + }] + + faultsim_restore_and_reopen + sqlite3changeset_apply db $C1 [list xConflict OMIT] + faultsim_save_and_close +} {} + +do_faultsim_test 2.2 -faults oom* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + sqlite3 db2 test.db2 +} -body { + set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] + set {} {} +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} +do_faultsim_test 2.3 -faults oom* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + sqlite3 db2 test.db2 +} -body { + set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]] + set {} {} +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} +do_faultsim_test 2.4 -faults oom* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]] +} -body { + sqlite3rebaser_create R + R configure $::rebase + R rebase $::C1 + set {} {} +} -test { + catch { R delete } + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} +do_faultsim_test 2.5 -faults oom* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] +} -body { + sqlite3rebaser_create R + R configure $::rebase + R rebase $::C1 + set {} {} +} -test { + catch { R delete } + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} + +} + +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(x PRIMARY KEY, y, z); + INSERT INTO t1 VALUES(3, 1, 4); + INSERT INTO t1 VALUES(1, 5, 9); +} +faultsim_save_and_close + +proc xConflict {ret args} { return $ret } + +do_test 3.1 { + faultsim_restore_and_reopen + + execsql { BEGIN; UPDATE t1 SET z=11; } + set C1 [changeset_from_sql { + UPDATE t1 SET z=10 WHERE x=1; + }] + execsql { ROLLBACK } + + execsql { BEGIN; UPDATE t1 SET z=11; } + set C2 [changeset_from_sql { + UPDATE t1 SET z=55 WHERE x=1; + }] + execsql { ROLLBACK } + + set ::rebase1 [sqlite3changeset_apply_v2 db $::C1 [list xConflict OMIT]] + set ::rebase2 [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] + set {} {} + execsql { SELECT * FROM t1 } +} {3 1 4 1 5 9} + + +do_faultsim_test 3.2 -faults oom* -prep { + faultsim_restore_and_reopen +} -body { + sqlite3rebaser_create R + R configure $::rebase1 + R configure $::rebase2 + set {} {} +} -test { + catch { R delete } + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} + + finish_test diff --git a/ext/session/sessionrebase.test b/ext/session/sessionrebase.test new file mode 100644 index 0000000000..ced9f2240d --- /dev/null +++ b/ext/session/sessionrebase.test @@ -0,0 +1,477 @@ +# 2018 March 14 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionrebase + +set ::lConflict [list] +proc xConflict {args} { + set res [lindex $::lConflict 0] + set ::lConflict [lrange $::lConflict 1 end] + return $res +} + +#------------------------------------------------------------------------- +# The following test cases - 1.* - test that the rebase blobs output by +# sqlite3_changeset_apply_v2 look correct in some simple cases. The blob +# is itself a changeset, containing records determined as follows: +# +# * For each conflict resolved with REPLACE, the rebase blob contains +# a DELETE record. All fields other than the PK fields are undefined. +# +# * For each conflict resolved with OMIT, the rebase blob contains an +# INSERT record. For an INSERT or UPDATE operation, the indirect flag +# is clear and all updated fields are defined. For a DELETE operation, +# the indirect flag is set and all non-PK fields left undefined. +# +proc do_apply_v2_test {tn sql modsql conflict_handler res} { + + execsql BEGIN + sqlite3session S db main + S attach * + execsql $sql + set changeset [S changeset] + S delete + execsql ROLLBACK + + execsql BEGIN + execsql $modsql + set ::lConflict $conflict_handler + set blob [sqlite3changeset_apply_v2 db $changeset xConflict] + execsql ROLLBACK + + uplevel [list do_test $tn [list changeset_to_list $blob] [list {*}$res]] +} + + +set ::lConflict [list] +proc xConflict {args} { + set res [lindex $::lConflict 0] + set ::lConflict [lrange $::lConflict 1 end] + return $res +} + +# Take a copy of database test.db in file test.db2. Execute $sql1 +# against test.db and $sql2 against test.db2. Capture a changeset +# for each. Then send the test.db2 changeset to test.db and apply +# it with the conflict handlers in $conflict_handler. Patch the +# test.db changeset and then execute it against test.db2. Test that +# the two databases come out the same. +# +proc do_rebase_test {tn sql1 sql2 conflict_handler {testsql ""} {testres ""}} { + + for {set i 1} {$i <= 2} {incr i} { + forcedelete test.db2 test.db2-journal test.db2-wal + forcecopy test.db test.db2 + sqlite3 db2 test.db2 + + db eval BEGIN + + sqlite3session S1 db main + S1 attach * + execsql $sql1 db + set c1 [S1 changeset] + S1 delete + + if {$i==1} { + sqlite3session S2 db2 main + S2 attach * + execsql $sql2 db2 + set c2 [S2 changeset] + S2 delete + } else { + set c2 [list] + foreach sql [split $sql2 ";"] { + if {[string is space $sql]} continue + sqlite3session S2 db2 main + S2 attach * + execsql $sql db2 + lappend c2 [S2 changeset] + S2 delete + } + } + + set ::lConflict $conflict_handler + set rebase [list] + if {$i==1} { + lappend rebase [sqlite3changeset_apply_v2 db $c2 xConflict] + } else { + foreach c $c2 { +#puts "apply_v2: [changeset_to_list $c]" + lappend rebase [sqlite3changeset_apply_v2 db $c xConflict] + } + #puts "llength: [llength $rebase]" + } + #if {$tn=="2.1.4"} { puts [changeset_to_list $rebase] ; breakpoint } + #puts [changeset_to_list [lindex $rebase 0]] ; breakpoint + #puts [llength $rebase] + + sqlite3rebaser_create R + foreach r $rebase { +#puts [changeset_to_list $r] + R configure $r + } + set c1r [R rebase $c1] + R delete + #if {$tn=="2.1.4"} { puts [changeset_to_list $c1r] } + + sqlite3changeset_apply_v2 db2 $c1r xConflictAbort + + if {[string range $tn end end]!="*"} { + uplevel [list do_test $tn.$i.1 [list compare_db db db2] {}] + } + db2 close + + if {$testsql!=""} { + uplevel [list do_execsql_test $tn.$i.2 $testsql $testres] + } + + db eval ROLLBACK + } +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'value A'); +} + +do_apply_v2_test 1.1.1 { + UPDATE t1 SET b = 'value B' WHERE a=1; +} { + UPDATE t1 SET b = 'value C' WHERE a=1; +} { + OMIT +} { + {INSERT t1 0 X. {} {i 1 t {value B}}} +} + +do_apply_v2_test 1.1.2 { + UPDATE t1 SET b = 'value B' WHERE a=1; +} { + UPDATE t1 SET b = 'value C' WHERE a=1; +} { + REPLACE +} { + {INSERT t1 1 X. {} {i 1 t {value B}}} +} + +do_apply_v2_test 1.2.1 { + INSERT INTO t1 VALUES(2, 'first'); +} { + INSERT INTO t1 VALUES(2, 'second'); +} { + OMIT +} { + {INSERT t1 0 X. {} {i 2 t first}} +} +do_apply_v2_test 1.2.2 { + INSERT INTO t1 VALUES(2, 'first'); +} { + INSERT INTO t1 VALUES(2, 'second'); +} { + REPLACE +} { + {INSERT t1 1 X. {} {i 2 t first}} +} + +do_apply_v2_test 1.3.1 { + DELETE FROM t1 WHERE a=1; +} { + UPDATE t1 SET b='value D' WHERE a=1; +} { + OMIT +} { + {DELETE t1 0 X. {i 1 t {value A}} {}} +} +do_apply_v2_test 1.3.2 { + DELETE FROM t1 WHERE a=1; +} { + UPDATE t1 SET b='value D' WHERE a=1; +} { + REPLACE +} { + {DELETE t1 1 X. {i 1 t {value A}} {}} +} + +#------------------------------------------------------------------------- +# Test cases 2.* - simple tests of rebasing actual changesets. +# +# 2.1.1 - 1u2u1r +# 2.1.2 - 1u2u2r +# 2.1.3 - 1d2d +# 2.1.4 - 1d2u1r +# 2.1.5 - 1d2u2r !! +# 2.1.6 - 1u2d1r +# 2.1.7 - 1u2d2r +# +# 2.1.8 - 1i2i2r +# 2.1.9 - 1i2i1r +# + +proc xConflictAbort {args} { + return "ABORT" +} + +reset_db +do_execsql_test 2.1.0 { + CREATE TABLE t1 (a INTEGER PRIMARY KEY, b TEXT); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); +} +do_rebase_test 2.1.1 { + UPDATE t1 SET b = 'two.1' WHERE a=2 +} { + UPDATE t1 SET b = 'two.2' WHERE a=2; +} { + OMIT +} { SELECT * FROM t1 } {1 one 2 two.1 3 three} + +do_rebase_test 2.1.2 { + UPDATE t1 SET b = 'two.1' WHERE a=2 +} { + UPDATE t1 SET b = 'two.2' WHERE a=2; +} { + REPLACE +} { SELECT * FROM t1 } {1 one 2 two.2 3 three} + +do_rebase_test 2.1.3 { + DELETE FROM t1 WHERE a=3 +} { + DELETE FROM t1 WHERE a=3; +} { + OMIT +} { SELECT * FROM t1 } {1 one 2 two} + +do_rebase_test 2.1.4 { + DELETE FROM t1 WHERE a=1 +} { + UPDATE t1 SET b='one.2' WHERE a=1 +} { + OMIT +} { SELECT * FROM t1 } {2 two 3 three} + +#do_rebase_test 2.1.5 { +# DELETE FROM t1 WHERE a=1; +#} { +# UPDATE t1 SET b='one.2' WHERE a=1 +#} { +# REPLACE +#} { SELECT * FROM t1 } {2 two 3 three} + +do_rebase_test 2.1.6 { + UPDATE t1 SET b='three.1' WHERE a=3 +} { + DELETE FROM t1 WHERE a=3; +} { + OMIT +} { SELECT * FROM t1 } {1 one 2 two 3 three.1} + +do_rebase_test 2.1.7 { + UPDATE t1 SET b='three.1' WHERE a=3 +} { + DELETE FROM t1 WHERE a=3; +} { + REPLACE +} { SELECT * FROM t1 } {1 one 2 two} + +do_rebase_test 2.1.8 { + INSERT INTO t1 VALUES(4, 'four.1') +} { + INSERT INTO t1 VALUES(4, 'four.2'); +} { + REPLACE +} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.2} + +do_rebase_test 2.1.9 { + INSERT INTO t1 VALUES(4, 'four.1') +} { + INSERT INTO t1 VALUES(4, 'four.2'); +} { + OMIT +} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.1} + +do_execsql_test 2.2.0 { + CREATE TABLE t2(x, y, z PRIMARY KEY); + INSERT INTO t2 VALUES('i', 'a', 'A'); + INSERT INTO t2 VALUES('ii', 'b', 'B'); + INSERT INTO t2 VALUES('iii', 'c', 'C'); + + CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t3 VALUES(-1, 'z', 'Z'); + INSERT INTO t3 VALUES(-2, 'y', 'Y'); +} + +do_rebase_test 2.2.1 { + UPDATE t2 SET x=1 WHERE z='A' +} { + UPDATE t2 SET y='one' WHERE z='A'; +} { +} { SELECT * FROM t2 WHERE z='A' } { 1 one A } + +do_rebase_test 2.2.2 { + UPDATE t2 SET x=1, y='one' WHERE z='B' +} { + UPDATE t2 SET y='two' WHERE z='B'; +} { + REPLACE +} { SELECT * FROM t2 WHERE z='B' } { 1 two B } + +do_rebase_test 2.2.3 { + UPDATE t2 SET x=1, y='one' WHERE z='B' +} { + UPDATE t2 SET y='two' WHERE z='B'; +} { + OMIT +} { SELECT * FROM t2 WHERE z='B' } { 1 one B } + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c)); + CREATE TABLE abcdefghijkl(x PRIMARY KEY, y, z); + + INSERT INTO t3 VALUES(1, 2, 3); + INSERT INTO t3 VALUES(4, 2, 5); + INSERT INTO t3 VALUES(7, 2, 9); + + INSERT INTO abcdefghijkl VALUES('a', 'b', 'c'); + INSERT INTO abcdefghijkl VALUES('d', 'e', 'f'); + INSERT INTO abcdefghijkl VALUES('g', 'h', 'i'); +} + +breakpoint +# do_rebase_test 3.6.tn { +# UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; +# } { +# UPDATE abcdefghijkl SET y=1 WHERE x='d'; +# UPDATE abcdefghijkl SET z=1 WHERE x='d'; +# } [list REPLACE REPLACE REPLACE] + +foreach {tn p} { + 1 OMIT 2 REPLACE +} { + do_rebase_test 3.1.$tn { + INSERT INTO t3 VALUES(1, 1, 1); + UPDATE abcdefghijkl SET y=2; + } { + INSERT INTO t3 VALUES(4, 1, 1); + DELETE FROM abcdefghijkl; + } [list $p $p $p $p $p $p $p $p] + + do_rebase_test 3.2.$tn { + INSERT INTO abcdefghijkl SELECT * FROM t3; + UPDATE t3 SET b=b+1; + } { + INSERT INTO t3 VALUES(3, 3, 3); + INSERT INTO abcdefghijkl SELECT * FROM t3; + } [list $p $p $p $p $p $p $p $p] + + do_rebase_test 3.3.$tn { + INSERT INTO abcdefghijkl VALUES(22, 23, 24); + } { + INSERT INTO abcdefghijkl VALUES(22, 25, 26); + UPDATE abcdefghijkl SET y=400 WHERE x=22; + } [list $p $p $p $p $p $p $p $p] + + do_rebase_test 3.4.$tn { + INSERT INTO abcdefghijkl VALUES(22, 23, 24); + } { + INSERT INTO abcdefghijkl VALUES(22, 25, 26); + UPDATE abcdefghijkl SET y=400 WHERE x=22; + } [list REPLACE $p] + + do_rebase_test 3.5.$tn* { + UPDATE abcdefghijkl SET y='X' WHERE x='d'; + } { + DELETE FROM abcdefghijkl WHERE x='d'; + INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); + } [list $p $p $p] + do_rebase_test 3.5.$tn { + UPDATE abcdefghijkl SET y='X' WHERE x='d'; + } { + DELETE FROM abcdefghijkl WHERE x='d'; + INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); + } [list REPLACE $p $p] + + do_rebase_test 3.6.$tn { + UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; + } { + UPDATE abcdefghijkl SET y=1 WHERE x='d'; + UPDATE abcdefghijkl SET z=1 WHERE x='d'; + } [list REPLACE $p $p] +} + +#------------------------------------------------------------------------- +# Check that apply_v2() does not create a rebase buffer for a patchset. +# And that it is not possible to rebase a patchset. +# +do_execsql_test 4.0 { + CREATE TABLE t5(o PRIMARY KEY, p, q); + INSERT INTO t5 VALUES(1, 2, 3); + INSERT INTO t5 VALUES(4, 5, 6); +} +foreach {tn cmd rebasable} { + 1 patchset 0 + 2 changeset 1 +} { + proc xConflict {args} { return "OMIT" } + do_test 4.1.$tn { + execsql { + BEGIN; + DELETE FROM t5 WHERE o=4; + } + + sqlite3session S db main + S attach * + execsql { + INSERT INTO t5 VALUES(4, 'five', 'six'); + } + set P [S $cmd] + S delete + + execsql ROLLBACK; + + set ::rebase [sqlite3changeset_apply_v2 db $P xConflict] + expr [llength $::rebase]>0 + } $rebasable +} + +foreach {tn cmd rebasable} { + 1 patchset 0 + 2 changeset 1 +} { + do_test 4.2.$tn { + sqlite3session S db main + S attach * + execsql { + INSERT INTO t5 VALUES(5+$tn, 'five', 'six'); + } + set P [S $cmd] + S delete + + sqlite3rebaser_create R + R configure $::rebase + expr [catch {R rebase $P}]==0 + } $rebasable + + catch { R delete } +} +finish_test + diff --git a/ext/session/sessionstat1.test b/ext/session/sessionstat1.test new file mode 100644 index 0000000000..082c02bcf1 --- /dev/null +++ b/ext/session/sessionstat1.test @@ -0,0 +1,311 @@ +# 2018 January 12 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionstat1 + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE INDEX t1b ON t1(b); + CREATE INDEX t1c ON t1(c); + + WITH s(i) AS ( + SELECT 0 UNION ALL SELECT i+1 FROM s WHERE (i+1)<32 + ) + INSERT INTO t1 SELECT i, i%8, i%2 FROM s; +} + +do_iterator_test 1.1 {} { + ANALYZE +} { + {INSERT sqlite_stat1 0 XX. {} {t t1 t sqlite_autoindex_t1_1 t {32 1}}} + {INSERT sqlite_stat1 0 XX. {} {t t1 t t1b t {32 4}}} + {INSERT sqlite_stat1 0 XX. {} {t t1 t t1c t {32 16}}} +} + +do_execsql_test 1.2 { + WITH s(i) AS ( + SELECT 32 UNION ALL SELECT i+1 FROM s WHERE (i+1)<64 + ) + INSERT INTO t1 SELECT i, i%8, i%2 FROM s; +} + +do_iterator_test 1.3 {} { + ANALYZE +} { + {UPDATE sqlite_stat1 0 XX. {t t1 t sqlite_autoindex_t1_1 t {32 1}} {{} {} {} {} t {64 1}}} + {UPDATE sqlite_stat1 0 XX. {t t1 t t1b t {32 4}} {{} {} {} {} t {64 8}}} + {UPDATE sqlite_stat1 0 XX. {t t1 t t1c t {32 16}} {{} {} {} {} t {64 32}}} +} + +do_iterator_test 1.5 {} { + DROP INDEX t1b; +} { + {DELETE sqlite_stat1 0 XX. {t t1 t t1b t {64 8}} {}} +} + +do_iterator_test 1.6 {} { + DROP TABLE t1; +} { + {DELETE sqlite_stat1 0 XX. {t t1 t sqlite_autoindex_t1_1 t {64 1}} {}} + {DELETE sqlite_stat1 0 XX. {t t1 t t1c t {64 32}} {}} +} + +#------------------------------------------------------------------------- +# +catch { db2 close } +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 2.0 { + do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE INDEX t1b ON t1(b); + CREATE INDEX t1c ON t1(c); + ANALYZE; + } +} {} + +do_test 2.1 { + do_then_apply_sql { + WITH s(i) AS ( + SELECT 0 UNION ALL SELECT i+1 FROM s WHERE (i+1)<32 + ) + INSERT INTO t1 SELECT i, i%8, i%2 FROM s; + ANALYZE; + } +} {} + +do_execsql_test -db db2 2.2 { + SELECT * FROM sqlite_stat1 +} { + t1 sqlite_autoindex_t1_1 {32 1} + t1 t1b {32 4} + t1 t1c {32 16} +} + +do_test 2.3 { + do_then_apply_sql { DROP INDEX t1c } +} {} + +do_execsql_test -db db2 2.4 { + SELECT * FROM sqlite_stat1 +} { + t1 sqlite_autoindex_t1_1 {32 1} + t1 t1b {32 4} +} + +do_test 2.3 { + do_then_apply_sql { DROP TABLE t1 } +} {} + +do_execsql_test -db db2 2.4 { + SELECT * FROM sqlite_stat1 +} { +} + +do_execsql_test -db db2 2.5 { SELECT count(*) FROM t1 } 32 + +#------------------------------------------------------------------------- +db2 close +forcedelete test.db2 +reset_db +sqlite3 db2 test.db2 + +do_test 3.0 { + do_common_sql { + CREATE TABLE t1(a, b, c); + ANALYZE; + DELETE FROM sqlite_stat1; + } + execsql { + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + INSERT INTO t1 VALUES(4, 4, 4); + } +} {} + +do_iterator_test 3.1 {} { + ANALYZE +} { + {INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 4}} +} +db null null +db2 null null +do_execsql_test 3.2 { + SELECT * FROM sqlite_stat1; +} {t1 null 4} +do_test 3.3 { + execsql { DELETE FROM sqlite_stat1 } + do_then_apply_sql { ANALYZE } + execsql { SELECT * FROM sqlite_stat1 } db2 +} {t1 null 4} +do_test 3.4 { + execsql { INSERT INTO t1 VALUES(5,5,5) } + do_then_apply_sql { ANALYZE } + execsql { SELECT * FROM sqlite_stat1 } db2 +} {t1 null 5} +do_test 3.5 { + do_then_apply_sql { DROP TABLE t1 } + execsql { SELECT * FROM sqlite_stat1 } db2 +} {} + +do_test 3.6.1 { + execsql { + CREATE TABLE t1(a, b, c); + CREATE TABLE t2(x, y, z); + INSERT INTO t1 VALUES(1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5); + INSERT INTO t2 SELECT * FROM t1; + DELETE FROM sqlite_stat1; + } + sqlite3session S db main + S attach sqlite_stat1 + execsql { ANALYZE } +} {} +do_changeset_test 3.6.2 S { + {INSERT sqlite_stat1 0 XX. {} {t t2 b {} t 5}} + {INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 5}} +} +do_changeset_invert_test 3.6.3 S { + {DELETE sqlite_stat1 0 XX. {t t2 b {} t 5} {}} + {DELETE sqlite_stat1 0 XX. {t t1 b {} t 5} {}} +} +do_test 3.6.4 { S delete } {} + +proc sql_changeset_concat {args} { + foreach sql $args { + sqlite3session S db main + S attach sqlite_stat1 + execsql $sql + set change [S changeset] + S delete + + if {[info vars ret]!=""} { + set ret [sqlite3changeset_concat $ret $change] + } else { + set ret $change + } + } + + changeset_to_list $ret +} + +proc do_scc_test {tn args} { + uplevel [list \ + do_test $tn [concat sql_changeset_concat [lrange $args 0 end-1]] \ + [list {*}[ lindex $args end ]] + ] +} + +do_execsql_test 3.7.0 { + DELETE FROM sqlite_stat1; +} +do_scc_test 3.7.1 { + ANALYZE; +} { + INSERT INTO t2 VALUES(6,6,6); + ANALYZE; +} { + {INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 5}} + {INSERT sqlite_stat1 0 XX. {} {t t2 b {} t 6}} +} + +#------------------------------------------------------------------------- +catch { db2 close } +reset_db +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 4.1.0 { + do_common_sql { + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t1(b); + INSERT INTO t1 VALUES(1,1), (2,2); + ANALYZE; + } + execsql { DELETE FROM sqlite_stat1 } +} {} + +do_test 4.1.1 { + execsql { INSERT INTO t1 VALUES(3,3); } + set C [changeset_from_sql {ANALYZE}] + set ::c [list] + proc xConflict {args} { + lappend ::c $args + return "OMIT" + } + sqlite3changeset_apply db2 $C xConflict + set ::c +} [list {*}{ + {INSERT sqlite_stat1 CONFLICT {t t1 t i1 t {3 1}} {t t1 t i1 t {2 1}}} + {INSERT sqlite_stat1 CONFLICT {t t1 t i2 t {3 1}} {t t1 t i2 t {2 1}}} +}] + +do_execsql_test -db db2 4.1.2 { + SELECT * FROM sqlite_stat1 ORDER BY 1,2; +} {t1 i1 {2 1} t1 i2 {2 1}} + +do_test 4.1.3 { + proc xConflict {args} { + return "REPLACE" + } + sqlite3changeset_apply db2 $C xConflict + execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2 +} {t1 i1 {3 1} t1 i2 {3 1}} + +do_test 4.2.0 { + do_common_sql { + DROP TABLE t1; + CREATE TABLE t3(x,y); + INSERT INTO t3 VALUES('a','a'); + INSERT INTO t3 VALUES('b','b'); + ANALYZE; + } + execsql { DELETE FROM sqlite_stat1 } +} {} +do_test 4.2.1 { + execsql { INSERT INTO t3 VALUES('c','c'); } + set C [changeset_from_sql {ANALYZE}] + set ::c [list] + proc xConflict {args} { + lappend ::c $args + return "OMIT" + } + sqlite3changeset_apply db2 $C xConflict + set ::c +} [list {*}{ + {INSERT sqlite_stat1 CONFLICT {t t3 b {} t 3} {t t3 b {} t 2}} +}] + +db2 null null +do_execsql_test -db db2 4.2.2 { + SELECT * FROM sqlite_stat1 ORDER BY 1,2; +} {t3 null 2} + +do_test 4.2.3 { + proc xConflict {args} { + return "REPLACE" + } + sqlite3changeset_apply db2 $C xConflict + execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2 +} {t3 null 3} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index d5cb467374..abbf16dc75 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -46,6 +46,7 @@ struct sqlite3_session { int rc; /* Non-zero if an error has occurred */ void *pFilterCtx; /* First argument to pass to xTableFilter */ int (*xTableFilter)(void *pCtx, const char *zTab); + sqlite3_value *pZeroBlob; /* Value containing X'' */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ SessionHook hook; /* APIs to grab new and old data with */ @@ -67,7 +68,7 @@ struct SessionBuffer { ** sqlite3changeset_start_strm()). */ struct SessionInput { - int bNoDiscard; /* If true, discard no data */ + int bNoDiscard; /* If true, do not discard in InputBuffer() */ int iCurrent; /* Offset in aData[] of current change */ int iNext; /* Offset in aData[] of next change */ u8 *aData; /* Pointer to buffer containing changeset */ @@ -113,6 +114,7 @@ struct SessionTable { SessionTable *pNext; char *zName; /* Local name of table */ int nCol; /* Number of columns in table zName */ + int bStat1; /* True if this is sqlite_stat1 */ const char **azCol; /* Column names */ u8 *abPK; /* Array of primary key flags */ int nEntry; /* Total number of entries in hash table */ @@ -230,8 +232,8 @@ struct SessionTable { ** statement. ** ** For a DELETE change, all fields within the record except those associated -** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields -** contain the values identifying the row to delete. +** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the +** values identifying the row to delete. ** ** For an UPDATE change, all fields except those associated with PRIMARY KEY ** columns and columns that are modified by the UPDATE are set to "undefined". @@ -496,6 +498,7 @@ static int sessionPreupdateHash( h = sessionHashAppendBlob(h, n, z); }else{ assert( eType==SQLITE_NULL ); + assert( pTab->bStat1==0 || i!=1 ); *pbNullPK = 1; } } @@ -513,7 +516,7 @@ static int sessionPreupdateHash( static int sessionSerialLen(u8 *a){ int e = *a; int n; - if( e==0 ) return 1; + if( e==0 || e==0xFF ) return 1; if( e==SQLITE_NULL ) return 1; if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; return sessionVarintGet(&a[1], &n) + 1 + n; @@ -593,7 +596,7 @@ static int sessionChangeEqual( int n1 = sessionSerialLen(a1); int n2 = sessionSerialLen(a2); - if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ + if( n1!=n2 || memcmp(a1, a2, n1) ){ return 0; } a1 += n1; @@ -836,9 +839,8 @@ static int sessionPreupdateEqual( }else{ z = sqlite3_value_blob(pVal); } - if( memcmp(a, z, n) ) return 0; + if( n>0 && memcmp(a, z, n) ) return 0; a += n; - break; } } } @@ -894,9 +896,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ /* ** This function queries the database for the names of the columns of table -** zThis, in schema zDb. It is expected that the table has nCol columns. If -** not, SQLITE_SCHEMA is returned and none of the output variables are -** populated. +** zThis, in schema zDb. ** ** Otherwise, if they are not NULL, variable *pnCol is set to the number ** of columns in the database table and variable *pzTab is set to point to a @@ -917,9 +917,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ ** *pabPK = {1, 0, 0, 1} ** ** All returned buffers are part of the same single allocation, which must -** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then -** pointer *pazCol should be freed to release all memory. Otherwise, pointer -** *pabPK. It is illegal for both pazCol and pabPK to be NULL. +** be freed using sqlite3_free() by the caller */ static int sessionTableInfo( sqlite3 *db, /* Database connection */ @@ -944,7 +942,23 @@ static int sessionTableInfo( assert( pazCol && pabPK ); nThis = sqlite3Strlen30(zThis); - zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); + if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){ + rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); + if( rc==SQLITE_OK ){ + /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */ + zPragma = sqlite3_mprintf( + "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL " + "SELECT 1, 'idx', '', 0, '', 2 UNION ALL " + "SELECT 2, 'stat', '', 0, '', 0" + ); + }else if( rc==SQLITE_ERROR ){ + zPragma = sqlite3_mprintf(""); + }else{ + return rc; + } + }else{ + zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); + } if( !zPragma ) return SQLITE_NOMEM; rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); @@ -1036,11 +1050,55 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ break; } } + if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){ + pTab->bStat1 = 1; + } } } return (pSession->rc || pTab->abPK==0); } +/* +** Versions of the four methods in object SessionHook for use with the +** sqlite_stat1 table. The purpose of this is to substitute a zero-length +** blob each time a NULL value is read from the "idx" column of the +** sqlite_stat1 table. +*/ +typedef struct SessionStat1Ctx SessionStat1Ctx; +struct SessionStat1Ctx { + SessionHook hook; + sqlite3_session *pSession; +}; +static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){ + SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; + sqlite3_value *pVal = 0; + int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal); + if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){ + pVal = p->pSession->pZeroBlob; + } + *ppVal = pVal; + return rc; +} +static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){ + SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; + sqlite3_value *pVal = 0; + int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal); + if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){ + pVal = p->pSession->pZeroBlob; + } + *ppVal = pVal; + return rc; +} +static int sessionStat1Count(void *pCtx){ + SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; + return p->hook.xCount(p->hook.pCtx); +} +static int sessionStat1Depth(void *pCtx){ + SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; + return p->hook.xDepth(p->hook.pCtx); +} + + /* ** This function is only called from with a pre-update-hook reporting a ** change on table pTab (attached to session pSession). The type of change @@ -1057,6 +1115,7 @@ static void sessionPreupdateOneChange( int iHash; int bNull = 0; int rc = SQLITE_OK; + SessionStat1Ctx stat1 = {0}; if( pSession->rc ) return; @@ -1076,6 +1135,25 @@ static void sessionPreupdateOneChange( return; } + if( pTab->bStat1 ){ + stat1.hook = pSession->hook; + stat1.pSession = pSession; + pSession->hook.pCtx = (void*)&stat1; + pSession->hook.xNew = sessionStat1New; + pSession->hook.xOld = sessionStat1Old; + pSession->hook.xCount = sessionStat1Count; + pSession->hook.xDepth = sessionStat1Depth; + if( pSession->pZeroBlob==0 ){ + sqlite3_value *p = sqlite3ValueNew(0); + if( p==0 ){ + rc = SQLITE_NOMEM; + goto error_out; + } + sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC); + pSession->pZeroBlob = p; + } + } + /* Calculate the hash-key for this change. If the primary key of the row ** includes a NULL value, exit early. Such changes are ignored by the ** session module. */ @@ -1165,6 +1243,9 @@ static void sessionPreupdateOneChange( /* If an error has occurred, mark the session object as failed. */ error_out: + if( pTab->bStat1 ){ + pSession->hook = stat1.hook; + } if( rc!=SQLITE_OK ){ pSession->rc = rc; } @@ -1501,7 +1582,6 @@ int sqlite3session_diff( if( abPK[i] ) bHasPk = 1; } } - } sqlite3_free((char*)azCol); if( bMismatch ){ @@ -1627,6 +1707,7 @@ void sqlite3session_delete(sqlite3_session *pSession){ } } sqlite3_mutex_leave(sqlite3_db_mutex(db)); + sqlite3ValueFree(pSession->pZeroBlob); /* Delete all attached table objects. And the contents of their ** associated hash-tables. */ @@ -2094,28 +2175,42 @@ static int sessionSelectStmt( sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */ ){ int rc = SQLITE_OK; - int i; - const char *zSep = ""; - SessionBuffer buf = {0, 0, 0}; + char *zSql = 0; + int nSql = -1; - sessionAppendStr(&buf, "SELECT * FROM ", &rc); - sessionAppendIdent(&buf, zDb, &rc); - sessionAppendStr(&buf, ".", &rc); - sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " WHERE ", &rc); - for(i=0; ibEof && pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ + if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ int nMove = pIn->buf.nBuf - pIn->iNext; assert( nMove>=0 ); if( nMove>0 ){ @@ -2626,13 +2721,16 @@ static int sessionReadRecord( if( abPK && abPK[i]==0 ) continue; rc = sessionInputBuffer(pIn, 9); if( rc==SQLITE_OK ){ - eType = pIn->aData[pIn->iNext++]; - } - - assert( apOut[i]==0 ); - if( eType ){ - apOut[i] = sqlite3ValueNew(0); - if( !apOut[i] ) rc = SQLITE_NOMEM; + if( pIn->iNext>=pIn->nData ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + eType = pIn->aData[pIn->iNext++]; + assert( apOut[i]==0 ); + if( eType ){ + apOut[i] = sqlite3ValueNew(0); + if( !apOut[i] ) rc = SQLITE_NOMEM; + } + } } if( rc==SQLITE_OK ){ @@ -2642,10 +2740,14 @@ static int sessionReadRecord( pIn->iNext += sessionVarintGet(aVal, &nByte); rc = sessionInputBuffer(pIn, nByte); if( rc==SQLITE_OK ){ - u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); - rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc); + if( nByte<0 || nByte>pIn->nData-pIn->iNext ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); + rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc); + pIn->iNext += nByte; + } } - pIn->iNext += nByte; } if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ sqlite3_int64 v = sessionGetI64(aVal); @@ -2685,8 +2787,19 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ rc = sessionInputBuffer(pIn, 9); if( rc==SQLITE_OK ){ nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol); - rc = sessionInputBuffer(pIn, nRead+nCol+100); - nRead += nCol; + /* The hard upper limit for the number of columns in an SQLite + ** database table is, according to sqliteLimit.h, 32676. So + ** consider any table-header that purports to have more than 65536 + ** columns to be corrupt. This is convenient because otherwise, + ** if the (nCol>65536) condition below were omitted, a sufficiently + ** large value for nCol may cause nRead to wrap around and become + ** negative. Leading to a crash. */ + if( nCol<0 || nCol>65536 ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = sessionInputBuffer(pIn, nRead+nCol+100); + nRead += nCol; + } } while( rc==SQLITE_OK ){ @@ -2763,11 +2876,15 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ int nByte; int nVarint; nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol); - nCopy -= nVarint; - p->in.iNext += nVarint; - nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; - p->tblhdr.nBuf = 0; - sessionBufferGrow(&p->tblhdr, nByte, &rc); + if( p->nCol>0 ){ + nCopy -= nVarint; + p->in.iNext += nVarint; + nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; + p->tblhdr.nBuf = 0; + sessionBufferGrow(&p->tblhdr, nByte, &rc); + }else{ + rc = SQLITE_CORRUPT_BKPT; + } } if( rc==SQLITE_OK ){ @@ -2802,7 +2919,8 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ static int sessionChangesetNext( sqlite3_changeset_iter *p, /* Changeset iterator */ u8 **paRec, /* If non-NULL, store record pointer here */ - int *pnRec /* If non-NULL, store size of record here */ + int *pnRec, /* If non-NULL, store size of record here */ + int *pbNew /* If non-NULL, true if new table */ ){ int i; u8 op; @@ -2837,6 +2955,7 @@ static int sessionChangesetNext( op = p->in.aData[p->in.iNext++]; while( op=='T' || op=='P' ){ + if( pbNew ) *pbNew = 1; p->bPatchset = (op=='P'); if( sessionChangesetReadTblhdr(p) ) return p->rc; if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; @@ -2845,6 +2964,13 @@ static int sessionChangesetNext( op = p->in.aData[p->in.iNext++]; } + if( p->zTab==0 ){ + /* The first record in the changeset is not a table header. Must be a + ** corrupt changeset. */ + assert( p->in.iNext==1 ); + return (p->rc = SQLITE_CORRUPT_BKPT); + } + p->op = op; p->bIndirect = p->in.aData[p->in.iNext++]; if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ @@ -2887,9 +3013,9 @@ static int sessionChangesetNext( ** new.* to old.*, to accommodate the code that reads these arrays. */ for(i=0; inCol; i++){ assert( p->apValue[i]==0 ); - assert( p->abPK[i]==0 || p->apValue[i+p->nCol] ); if( p->abPK[i] ){ p->apValue[i] = p->apValue[i+p->nCol]; + if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT); p->apValue[i+p->nCol] = 0; } } @@ -2908,7 +3034,7 @@ static int sessionChangesetNext( ** callback by changeset_apply(). */ int sqlite3changeset_next(sqlite3_changeset_iter *p){ - return sessionChangesetNext(p, 0, 0); + return sessionChangesetNext(p, 0, 0, 0); } /* @@ -3284,9 +3410,11 @@ struct SessionApplyCtx { int nCol; /* Size of azCol[] and abPK[] arrays */ const char **azCol; /* Array of column names */ u8 *abPK; /* Boolean array - true if column is in PK */ - + int bStat1; /* True if table is sqlite_stat1 */ int bDeferConstraints; /* True to defer constraints */ SessionBuffer constraints; /* Deferred constraints are stored here */ + SessionBuffer rebase; /* Rebase information (if any) here */ + int bRebaseStarted; /* If table header is already in rebase */ }; /* @@ -3454,6 +3582,7 @@ static int sessionUpdateRow( return rc; } + /* ** Formulate and prepare an SQL statement to query table zTab by primary ** key. Assuming the following table structure: @@ -3515,6 +3644,46 @@ static int sessionInsertRow( return rc; } +static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){ + return sqlite3_prepare_v2(db, zSql, -1, pp, 0); +} + +/* +** Prepare statements for applying changes to the sqlite_stat1 table. +** These are similar to those created by sessionSelectRow(), +** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for +** other tables. +*/ +static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ + int rc = sessionSelectRow(db, "sqlite_stat1", p); + if( rc==SQLITE_OK ){ + rc = sessionPrepare(db, &p->pInsert, + "INSERT INTO main.sqlite_stat1 VALUES(?1, " + "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, " + "?3)" + ); + } + if( rc==SQLITE_OK ){ + rc = sessionPrepare(db, &p->pUpdate, + "UPDATE main.sqlite_stat1 SET " + "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, " + "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, " + "stat = CASE WHEN ?8 THEN ?9 ELSE stat END " + "WHERE tbl=?1 AND idx IS " + "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END " + "AND (?10 OR ?8=0 OR stat IS ?7)" + ); + } + if( rc==SQLITE_OK ){ + rc = sessionPrepare(db, &p->pDelete, + "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS " + "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END " + "AND (?4 OR stat IS ?3)" + ); + } + return rc; +} + /* ** A wrapper around sqlite3_bind_value() that detects an extra problem. ** See comments in the body of this function for details. @@ -3572,7 +3741,13 @@ static int sessionBindRow( if( !abPK || abPK[i] ){ sqlite3_value *pVal; (void)xValue(pIter, i, &pVal); - rc = sessionBindValue(pStmt, i+1, pVal); + if( pVal==0 ){ + /* The value in the changeset was "undefined". This indicates a + ** corrupt changeset blob. */ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = sessionBindValue(pStmt, i+1, pVal); + } } } return rc; @@ -3620,6 +3795,54 @@ static int sessionSeekToRow( return rc; } +/* +** This function is called from within sqlite3changset_apply_v2() when +** a conflict is encountered and resolved using conflict resolution +** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE).. +** It adds a conflict resolution record to the buffer in +** SessionApplyCtx.rebase, which will eventually be returned to the caller +** of apply_v2() as the "rebase" buffer. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int sessionRebaseAdd( + SessionApplyCtx *p, /* Apply context */ + int eType, /* Conflict resolution (OMIT or REPLACE) */ + sqlite3_changeset_iter *pIter /* Iterator pointing at current change */ +){ + int rc = SQLITE_OK; + int i; + int eOp = pIter->op; + if( p->bRebaseStarted==0 ){ + /* Append a table-header to the rebase buffer */ + const char *zTab = pIter->zTab; + sessionAppendByte(&p->rebase, 'T', &rc); + sessionAppendVarint(&p->rebase, p->nCol, &rc); + sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc); + sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc); + p->bRebaseStarted = 1; + } + + assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT ); + assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE ); + + sessionAppendByte(&p->rebase, + (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc + ); + sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc); + for(i=0; inCol; i++){ + sqlite3_value *pVal = 0; + if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){ + sqlite3changeset_old(pIter, i, &pVal); + }else{ + sqlite3changeset_new(pIter, i, &pVal); + } + sessionAppendValue(&p->rebase, pVal, &rc); + } + + return rc; +} + /* ** Invoke the conflict handler for the change that the changeset iterator ** currently points to. @@ -3695,7 +3918,7 @@ static int sessionConflictHandler( u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent]; int nBlob = pIter->in.iNext - pIter->in.iCurrent; sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc); - res = SQLITE_CHANGESET_OMIT; + return SQLITE_OK; }else{ /* No other row with the new.* primary key. */ res = xConflict(pCtx, eType+1, pIter); @@ -3721,6 +3944,9 @@ static int sessionConflictHandler( rc = SQLITE_MISUSE; break; } + if( rc==SQLITE_OK ){ + rc = sessionRebaseAdd(p, res, pIter); + } } return rc; @@ -3845,11 +4071,25 @@ static int sessionApplyOneOp( }else{ assert( op==SQLITE_INSERT ); - rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); - if( rc!=SQLITE_OK ) return rc; + if( p->bStat1 ){ + /* Check if there is a conflicting row. For sqlite_stat1, this needs + ** to be done using a SELECT, as there is no PRIMARY KEY in the + ** database schema to throw an exception if a duplicate is inserted. */ + rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); + if( rc==SQLITE_ROW ){ + rc = SQLITE_CONSTRAINT; + sqlite3_reset(p->pSelect); + } + } + + if( rc==SQLITE_OK ){ + rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); + if( rc!=SQLITE_OK ) return rc; + + sqlite3_step(p->pInsert); + rc = sqlite3_reset(p->pInsert); + } - sqlite3_step(p->pInsert); - rc = sqlite3_reset(p->pInsert); if( (rc&0xff)==SQLITE_CONSTRAINT ){ rc = sessionConflictHandler( SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace @@ -3882,42 +4122,42 @@ static int sessionApplyOneWithRetry( int rc; rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry); - assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) ); - - /* If the bRetry flag is set, the change has not been applied due to an - ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and - ** a row with the correct PK is present in the db, but one or more other - ** fields do not contain the expected values) and the conflict handler - ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation, - ** but pass NULL as the final argument so that sessionApplyOneOp() ignores - ** the SQLITE_CHANGESET_DATA problem. */ - if( bRetry ){ - assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE ); - rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); - } - - /* If the bReplace flag is set, the change is an INSERT that has not - ** been performed because the database already contains a row with the - ** specified primary key and the conflict handler returned - ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row - ** before reattempting the INSERT. */ - else if( bReplace ){ - assert( pIter->op==SQLITE_INSERT ); - rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); - if( rc==SQLITE_OK ){ - rc = sessionBindRow(pIter, - sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); - sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); - } - if( rc==SQLITE_OK ){ - sqlite3_step(pApply->pDelete); - rc = sqlite3_reset(pApply->pDelete); - } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ + /* If the bRetry flag is set, the change has not been applied due to an + ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and + ** a row with the correct PK is present in the db, but one or more other + ** fields do not contain the expected values) and the conflict handler + ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation, + ** but pass NULL as the final argument so that sessionApplyOneOp() ignores + ** the SQLITE_CHANGESET_DATA problem. */ + if( bRetry ){ + assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE ); rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); } - if( rc==SQLITE_OK ){ - rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); + + /* If the bReplace flag is set, the change is an INSERT that has not + ** been performed because the database already contains a row with the + ** specified primary key and the conflict handler returned + ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row + ** before reattempting the INSERT. */ + else if( bReplace ){ + assert( pIter->op==SQLITE_INSERT ); + rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = sessionBindRow(pIter, + sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); + sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); + } + if( rc==SQLITE_OK ){ + sqlite3_step(pApply->pDelete); + rc = sqlite3_reset(pApply->pDelete); + } + if( rc==SQLITE_OK ){ + rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); + } } } @@ -3993,10 +4233,12 @@ static int sessionChangesetApply( int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), - void *pCtx /* First argument passed to xConflict */ + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, /* OUT: Rebase information */ + int flags /* SESSION_APPLY_XXX flags */ ){ int schemaMismatch = 0; - int rc; /* Return code */ + int rc = SQLITE_OK; /* Return code */ const char *zTab = 0; /* Name of current table */ int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ @@ -4007,7 +4249,9 @@ static int sessionChangesetApply( pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sqlite3_mutex_enter(sqlite3_db_mutex(db)); - rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ + rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + } if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); } @@ -4031,9 +4275,18 @@ static int sessionChangesetApply( sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pSelect); - memset(&sApply, 0, sizeof(sApply)); sApply.db = db; + sApply.pDelete = 0; + sApply.pUpdate = 0; + sApply.pInsert = 0; + sApply.pSelect = 0; + sApply.nCol = 0; + sApply.azCol = 0; + sApply.abPK = 0; + sApply.bStat1 = 0; sApply.bDeferConstraints = 1; + sApply.bRebaseStarted = 0; + memset(&sApply.constraints, 0, sizeof(SessionBuffer)); /* If an xFilter() callback was specified, invoke it now. If the ** xFilter callback returns zero, skip this table. If it returns @@ -4082,12 +4335,20 @@ static int sessionChangesetApply( } else{ sApply.nCol = nCol; - if((rc = sessionSelectRow(db, zTab, &sApply)) - || (rc = sessionUpdateRow(db, zTab, &sApply)) - || (rc = sessionDeleteRow(db, zTab, &sApply)) - || (rc = sessionInsertRow(db, zTab, &sApply)) - ){ - break; + if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){ + if( (rc = sessionStat1Sql(db, &sApply) ) ){ + break; + } + sApply.bStat1 = 1; + }else{ + if((rc = sessionSelectRow(db, zTab, &sApply)) + || (rc = sessionUpdateRow(db, zTab, &sApply)) + || (rc = sessionDeleteRow(db, zTab, &sApply)) + || (rc = sessionInsertRow(db, zTab, &sApply)) + ){ + break; + } + sApply.bStat1 = 0; } } nTab = sqlite3Strlen30(zTab); @@ -4128,23 +4389,62 @@ static int sessionChangesetApply( } sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); - }else{ - sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); - sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); + if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); + }else{ + sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); + sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); + } } + if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){ + *ppRebase = (void*)sApply.rebase.aBuf; + *pnRebase = sApply.rebase.nBuf; + sApply.rebase.aBuf = 0; + } sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pSelect); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); + sqlite3_free((char*)sApply.rebase.aBuf); sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } +/* +** Apply the changeset passed via pChangeset/nChangeset to the main +** database attached to handle "db". +*/ +int sqlite3changeset_apply_v2( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +){ + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ + int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); + if( rc==SQLITE_OK ){ + rc = sessionChangesetApply( + db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags + ); + } + return rc; +} + /* ** Apply the changeset passed via pChangeset/nChangeset to the main database ** attached to handle "db". Invoke the supplied conflict handler callback @@ -4165,12 +4465,9 @@ int sqlite3changeset_apply( ), void *pCtx /* First argument passed to xConflict */ ){ - sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); - if( rc==SQLITE_OK ){ - rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx); - } - return rc; + return sqlite3changeset_apply_v2( + db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0 + ); } /* @@ -4178,6 +4475,32 @@ int sqlite3changeset_apply( ** attached to handle "db". Invoke the supplied conflict handler callback ** to resolve any conflicts encountered while applying the change. */ +int sqlite3changeset_apply_v2_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +){ + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ + int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); + if( rc==SQLITE_OK ){ + rc = sessionChangesetApply( + db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags + ); + } + return rc; +} int sqlite3changeset_apply_strm( sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ @@ -4193,12 +4516,9 @@ int sqlite3changeset_apply_strm( ), void *pCtx /* First argument passed to xConflict */ ){ - sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); - if( rc==SQLITE_OK ){ - rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx); - } - return rc; + return sqlite3changeset_apply_v2_strm( + db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0 + ); } /* @@ -4217,6 +4537,7 @@ struct sqlite3_changegroup { */ static int sessionChangeMerge( SessionTable *pTab, /* Table structure */ + int bRebase, /* True for a rebase hash-table */ int bPatchset, /* True for patchsets */ SessionChange *pExist, /* Existing change */ int op2, /* Second change operation */ @@ -4226,6 +4547,7 @@ static int sessionChangeMerge( SessionChange **ppNew /* OUT: Merged change */ ){ SessionChange *pNew = 0; + int rc = SQLITE_OK; if( !pExist ){ pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec); @@ -4235,9 +4557,66 @@ static int sessionChangeMerge( memset(pNew, 0, sizeof(SessionChange)); pNew->op = op2; pNew->bIndirect = bIndirect; - pNew->nRecord = nRec; pNew->aRecord = (u8*)&pNew[1]; - memcpy(pNew->aRecord, aRec, nRec); + if( bIndirect==0 || bRebase==0 ){ + pNew->nRecord = nRec; + memcpy(pNew->aRecord, aRec, nRec); + }else{ + int i; + u8 *pIn = aRec; + u8 *pOut = pNew->aRecord; + for(i=0; inCol; i++){ + int nIn = sessionSerialLen(pIn); + if( *pIn==0 ){ + *pOut++ = 0; + }else if( pTab->abPK[i]==0 ){ + *pOut++ = 0xFF; + }else{ + memcpy(pOut, pIn, nIn); + pOut += nIn; + } + pIn += nIn; + } + pNew->nRecord = pOut - pNew->aRecord; + } + }else if( bRebase ){ + if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){ + *ppNew = pExist; + }else{ + int nByte = nRec + pExist->nRecord + sizeof(SessionChange); + pNew = (SessionChange*)sqlite3_malloc(nByte); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + int i; + u8 *a1 = pExist->aRecord; + u8 *a2 = aRec; + u8 *pOut; + + memset(pNew, 0, nByte); + pNew->bIndirect = bIndirect || pExist->bIndirect; + pNew->op = op2; + pOut = pNew->aRecord = (u8*)&pNew[1]; + + for(i=0; inCol; i++){ + int n1 = sessionSerialLen(a1); + int n2 = sessionSerialLen(a2); + if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){ + *pOut++ = 0xFF; + }else if( *a2==0 ){ + memcpy(pOut, a1, n1); + pOut += n1; + }else{ + memcpy(pOut, a2, n2); + pOut += n2; + } + a1 += n1; + a2 += n2; + } + pNew->nRecord = pOut - pNew->aRecord; + } + sqlite3_free(pExist); + } }else{ int op1 = pExist->op; @@ -4331,7 +4710,7 @@ static int sessionChangeMerge( } *ppNew = pNew; - return SQLITE_OK; + return rc; } /* @@ -4340,15 +4719,15 @@ static int sessionChangeMerge( */ static int sessionChangesetToHash( sqlite3_changeset_iter *pIter, /* Iterator to read from */ - sqlite3_changegroup *pGrp /* Changegroup object to add changeset to */ + sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ + int bRebase /* True if hash table is for rebasing */ ){ u8 *aRec; int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; - - while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){ + while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ const char *zNew; int nCol; int op; @@ -4428,7 +4807,7 @@ static int sessionChangesetToHash( } } - rc = sessionChangeMerge(pTab, + rc = sessionChangeMerge(pTab, bRebase, pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange ); if( rc ) break; @@ -4487,13 +4866,12 @@ static int sessionChangegroupOutput( sessionAppendByte(&buf, p->op, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); + if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ + rc = xOutput(pOut, buf.aBuf, buf.nBuf); + buf.nBuf = 0; + } } } - - if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ - rc = xOutput(pOut, buf.aBuf, buf.nBuf); - buf.nBuf = 0; - } } if( rc==SQLITE_OK ){ @@ -4536,7 +4914,7 @@ int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){ rc = sqlite3changeset_start(&pIter, nData, pData); if( rc==SQLITE_OK ){ - rc = sessionChangesetToHash(pIter, pGrp); + rc = sessionChangesetToHash(pIter, pGrp, 0); } sqlite3changeset_finalize(pIter); return rc; @@ -4567,7 +4945,7 @@ int sqlite3changegroup_add_strm( rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); if( rc==SQLITE_OK ){ - rc = sessionChangesetToHash(pIter, pGrp); + rc = sessionChangesetToHash(pIter, pGrp, 0); } sqlite3changeset_finalize(pIter); return rc; @@ -4652,4 +5030,347 @@ int sqlite3changeset_concat_strm( return rc; } +/* +** Changeset rebaser handle. +*/ +struct sqlite3_rebaser { + sqlite3_changegroup grp; /* Hash table */ +}; + +/* +** Buffers a1 and a2 must both contain a sessions module record nCol +** fields in size. This function appends an nCol sessions module +** record to buffer pBuf that is a copy of a1, except that for +** each field that is undefined in a1[], swap in the field from a2[]. +*/ +static void sessionAppendRecordMerge( + SessionBuffer *pBuf, /* Buffer to append to */ + int nCol, /* Number of columns in each record */ + u8 *a1, int n1, /* Record 1 */ + u8 *a2, int n2, /* Record 2 */ + int *pRc /* IN/OUT: error code */ +){ + sessionBufferGrow(pBuf, n1+n2, pRc); + if( *pRc==SQLITE_OK ){ + int i; + u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; + for(i=0; inBuf = pOut-pBuf->aBuf; + assert( pBuf->nBuf<=pBuf->nAlloc ); + } +} + +/* +** This function is called when rebasing a local UPDATE change against one +** or more remote UPDATE changes. The aRec/nRec buffer contains the current +** old.* and new.* records for the change. The rebase buffer (a single +** record) is in aChange/nChange. The rebased change is appended to buffer +** pBuf. +** +** Rebasing the UPDATE involves: +** +** * Removing any changes to fields for which the corresponding field +** in the rebase buffer is set to "replaced" (type 0xFF). If this +** means the UPDATE change updates no fields, nothing is appended +** to the output buffer. +** +** * For each field modified by the local change for which the +** corresponding field in the rebase buffer is not "undefined" (0x00) +** or "replaced" (0xFF), the old.* value is replaced by the value +** in the rebase buffer. +*/ +static void sessionAppendPartialUpdate( + SessionBuffer *pBuf, /* Append record here */ + sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */ + u8 *aRec, int nRec, /* Local change */ + u8 *aChange, int nChange, /* Record to rebase against */ + int *pRc /* IN/OUT: Return Code */ +){ + sessionBufferGrow(pBuf, 2+nRec+nChange, pRc); + if( *pRc==SQLITE_OK ){ + int bData = 0; + u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; + int i; + u8 *a1 = aRec; + u8 *a2 = aChange; + + *pOut++ = SQLITE_UPDATE; + *pOut++ = pIter->bIndirect; + for(i=0; inCol; i++){ + int n1 = sessionSerialLen(a1); + int n2 = sessionSerialLen(a2); + if( pIter->abPK[i] || a2[0]==0 ){ + if( !pIter->abPK[i] ) bData = 1; + memcpy(pOut, a1, n1); + pOut += n1; + }else if( a2[0]!=0xFF ){ + bData = 1; + memcpy(pOut, a2, n2); + pOut += n2; + }else{ + *pOut++ = '\0'; + } + a1 += n1; + a2 += n2; + } + if( bData ){ + a2 = aChange; + for(i=0; inCol; i++){ + int n1 = sessionSerialLen(a1); + int n2 = sessionSerialLen(a2); + if( pIter->abPK[i] || a2[0]!=0xFF ){ + memcpy(pOut, a1, n1); + pOut += n1; + }else{ + *pOut++ = '\0'; + } + a1 += n1; + a2 += n2; + } + pBuf->nBuf = (pOut - pBuf->aBuf); + } + } +} + +/* +** pIter is configured to iterate through a changeset. This function rebases +** that changeset according to the current configuration of the rebaser +** object passed as the first argument. If no error occurs and argument xOutput +** is not NULL, then the changeset is returned to the caller by invoking +** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL, +** then (*ppOut) is set to point to a buffer containing the rebased changeset +** before this function returns. In this case (*pnOut) is set to the size of +** the buffer in bytes. It is the responsibility of the caller to eventually +** free the (*ppOut) buffer using sqlite3_free(). +** +** If an error occurs, an SQLite error code is returned. If ppOut and +** pnOut are not NULL, then the two output parameters are set to 0 before +** returning. +*/ +static int sessionRebase( + sqlite3_rebaser *p, /* Rebaser hash table */ + sqlite3_changeset_iter *pIter, /* Input data */ + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut, /* Context for xOutput callback */ + int *pnOut, /* OUT: Number of bytes in output changeset */ + void **ppOut /* OUT: Inverse of pChangeset */ +){ + int rc = SQLITE_OK; + u8 *aRec = 0; + int nRec = 0; + int bNew = 0; + SessionTable *pTab = 0; + SessionBuffer sOut = {0,0,0}; + + while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){ + SessionChange *pChange = 0; + int bDone = 0; + + if( bNew ){ + const char *zTab = pIter->zTab; + for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break; + } + bNew = 0; + + /* A patchset may not be rebased */ + if( pIter->bPatchset ){ + rc = SQLITE_ERROR; + } + + /* Append a table header to the output for this new table */ + sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc); + sessionAppendVarint(&sOut, pIter->nCol, &rc); + sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc); + sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc); + } + + if( pTab && rc==SQLITE_OK ){ + int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange); + + for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){ + if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){ + break; + } + } + } + + if( pChange ){ + assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT ); + switch( pIter->op ){ + case SQLITE_INSERT: + if( pChange->op==SQLITE_INSERT ){ + bDone = 1; + if( pChange->bIndirect==0 ){ + sessionAppendByte(&sOut, SQLITE_UPDATE, &rc); + sessionAppendByte(&sOut, pIter->bIndirect, &rc); + sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc); + sessionAppendBlob(&sOut, aRec, nRec, &rc); + } + } + break; + + case SQLITE_UPDATE: + bDone = 1; + if( pChange->op==SQLITE_DELETE ){ + if( pChange->bIndirect==0 ){ + u8 *pCsr = aRec; + sessionSkipRecord(&pCsr, pIter->nCol); + sessionAppendByte(&sOut, SQLITE_INSERT, &rc); + sessionAppendByte(&sOut, pIter->bIndirect, &rc); + sessionAppendRecordMerge(&sOut, pIter->nCol, + pCsr, nRec-(pCsr-aRec), + pChange->aRecord, pChange->nRecord, &rc + ); + } + }else{ + sessionAppendPartialUpdate(&sOut, pIter, + aRec, nRec, pChange->aRecord, pChange->nRecord, &rc + ); + } + break; + + default: + assert( pIter->op==SQLITE_DELETE ); + bDone = 1; + if( pChange->op==SQLITE_INSERT ){ + sessionAppendByte(&sOut, SQLITE_DELETE, &rc); + sessionAppendByte(&sOut, pIter->bIndirect, &rc); + sessionAppendRecordMerge(&sOut, pIter->nCol, + pChange->aRecord, pChange->nRecord, aRec, nRec, &rc + ); + } + break; + } + } + + if( bDone==0 ){ + sessionAppendByte(&sOut, pIter->op, &rc); + sessionAppendByte(&sOut, pIter->bIndirect, &rc); + sessionAppendBlob(&sOut, aRec, nRec, &rc); + } + if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){ + rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); + sOut.nBuf = 0; + } + if( rc ) break; + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(sOut.aBuf); + memset(&sOut, 0, sizeof(sOut)); + } + + if( rc==SQLITE_OK ){ + if( xOutput ){ + if( sOut.nBuf>0 ){ + rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); + } + }else{ + *ppOut = (void*)sOut.aBuf; + *pnOut = sOut.nBuf; + sOut.aBuf = 0; + } + } + sqlite3_free(sOut.aBuf); + return rc; +} + +/* +** Create a new rebaser object. +*/ +int sqlite3rebaser_create(sqlite3_rebaser **ppNew){ + int rc = SQLITE_OK; + sqlite3_rebaser *pNew; + + pNew = sqlite3_malloc(sizeof(sqlite3_rebaser)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pNew, 0, sizeof(sqlite3_rebaser)); + } + *ppNew = pNew; + return rc; +} + +/* +** Call this one or more times to configure a rebaser. +*/ +int sqlite3rebaser_configure( + sqlite3_rebaser *p, + int nRebase, const void *pRebase +){ + sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ + int rc; /* Return code */ + rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase); + if( rc==SQLITE_OK ){ + rc = sessionChangesetToHash(pIter, &p->grp, 1); + } + sqlite3changeset_finalize(pIter); + return rc; +} + +/* +** Rebase a changeset according to current rebaser configuration +*/ +int sqlite3rebaser_rebase( + sqlite3_rebaser *p, + int nIn, const void *pIn, + int *pnOut, void **ppOut +){ + sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ + int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn); + + if( rc==SQLITE_OK ){ + rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut); + sqlite3changeset_finalize(pIter); + } + + return rc; +} + +/* +** Rebase a changeset according to current rebaser configuration +*/ +int sqlite3rebaser_rebase_strm( + sqlite3_rebaser *p, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +){ + sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ + int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); + + if( rc==SQLITE_OK ){ + rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0); + sqlite3changeset_finalize(pIter); + } + + return rc; +} + +/* +** Destroy a rebaser object +*/ +void sqlite3rebaser_delete(sqlite3_rebaser *p){ + if( p ){ + sessionDeleteTable(p->grp.pList); + sqlite3_free(p); + } +} + #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 0882cf34cf..a3def5f1df 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -13,16 +13,23 @@ extern "C" { /* ** CAPI3REF: Session Object Handle +** +** An instance of this object is a [session] that can be used to +** record changes to a database. */ typedef struct sqlite3_session sqlite3_session; /* ** CAPI3REF: Changeset Iterator Handle +** +** An instance of this object acts as a cursor for iterating +** over the elements of a [changeset] or [patchset]. */ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; /* ** CAPI3REF: Create A New Session Object +** CONSTRUCTOR: sqlite3_session ** ** Create a new session object attached to database handle db. If successful, ** a pointer to the new object is written to *ppSession and SQLITE_OK is @@ -59,6 +66,7 @@ int sqlite3session_create( /* ** CAPI3REF: Delete A Session Object +** DESTRUCTOR: sqlite3_session ** ** Delete a session object previously allocated using ** [sqlite3session_create()]. Once a session object has been deleted, the @@ -74,6 +82,7 @@ void sqlite3session_delete(sqlite3_session *pSession); /* ** CAPI3REF: Enable Or Disable A Session Object +** METHOD: sqlite3_session ** ** Enable or disable the recording of changes by a session object. When ** enabled, a session object records changes made to the database. When @@ -93,6 +102,7 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* ** CAPI3REF: Set Or Clear the Indirect Change Flag +** METHOD: sqlite3_session ** ** Each change recorded by a session object is marked as either direct or ** indirect. A change is marked as indirect if either: @@ -122,6 +132,7 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); /* ** CAPI3REF: Attach A Table To A Session Object +** METHOD: sqlite3_session ** ** If argument zTab is not NULL, then it is the name of a table to attach ** to the session object passed as the first argument. All subsequent changes @@ -147,6 +158,35 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); ** ** SQLITE_OK is returned if the call completes without error. Or, if an error ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. +** +**

Special sqlite_stat1 Handling

+** +** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to +** some of the rules above. In SQLite, the schema of sqlite_stat1 is: +**
+**        CREATE TABLE sqlite_stat1(tbl,idx,stat)  
+**  
+** +** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are +** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes +** are recorded for rows for which (idx IS NULL) is true. However, for such +** rows a zero-length blob (SQL value X'') is stored in the changeset or +** patchset instead of a NULL value. This allows such changesets to be +** manipulated by legacy implementations of sqlite3changeset_invert(), +** concat() and similar. +** +** The sqlite3changeset_apply() function automatically converts the +** zero-length blob back to a NULL value when updating the sqlite_stat1 +** table. However, if the application calls sqlite3changeset_new(), +** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset +** iterator directly (including on a changeset iterator passed to a +** conflict-handler callback) then the X'' value is returned. The application +** must translate X'' to NULL itself if required. +** +** Legacy (older than 3.22.0) versions of the sessions module cannot capture +** changes made to the sqlite_stat1 table. Legacy versions of the +** sqlite3changeset_apply() function silently ignore any modifications to the +** sqlite_stat1 table that are part of a changeset or patchset. */ int sqlite3session_attach( sqlite3_session *pSession, /* Session object */ @@ -155,6 +195,7 @@ int sqlite3session_attach( /* ** CAPI3REF: Set a table filter on a Session Object. +** METHOD: sqlite3_session ** ** The second argument (xFilter) is the "filter callback". For changes to rows ** in tables that are not attached to the Session object, the filter is called @@ -173,6 +214,7 @@ void sqlite3session_table_filter( /* ** CAPI3REF: Generate A Changeset From A Session Object +** METHOD: sqlite3_session ** ** Obtain a changeset containing changes to the tables attached to the ** session object passed as the first argument. If successful, @@ -282,7 +324,8 @@ int sqlite3session_changeset( ); /* -** CAPI3REF: Load The Difference Between Tables Into A Session +** CAPI3REF: Load The Difference Between Tables Into A Session +** METHOD: sqlite3_session ** ** If it is not already attached to the session object passed as the first ** argument, this function attaches table zTbl in the same manner as the @@ -347,6 +390,7 @@ int sqlite3session_diff( /* ** CAPI3REF: Generate A Patchset From A Session Object +** METHOD: sqlite3_session ** ** The differences between a patchset and a changeset are that: ** @@ -375,8 +419,8 @@ int sqlite3session_diff( */ int sqlite3session_patchset( sqlite3_session *pSession, /* Session object */ - int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ - void **ppPatchset /* OUT: Buffer containing changeset */ + int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */ + void **ppPatchset /* OUT: Buffer containing patchset */ ); /* @@ -398,6 +442,7 @@ int sqlite3session_isempty(sqlite3_session *pSession); /* ** CAPI3REF: Create An Iterator To Traverse A Changeset +** CONSTRUCTOR: sqlite3_changeset_iter ** ** Create an iterator used to iterate through the contents of a changeset. ** If successful, *pp is set to point to the iterator handle and SQLITE_OK @@ -438,6 +483,7 @@ int sqlite3changeset_start( /* ** CAPI3REF: Advance A Changeset Iterator +** METHOD: sqlite3_changeset_iter ** ** This function may only be used with iterators created by function ** [sqlite3changeset_start()]. If it is called on an iterator passed to @@ -462,6 +508,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); /* ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator +** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator @@ -496,6 +543,7 @@ int sqlite3changeset_op( /* ** CAPI3REF: Obtain The Primary Key Definition Of A Table +** METHOD: sqlite3_changeset_iter ** ** For each modified table, a changeset includes the following: ** @@ -527,6 +575,7 @@ int sqlite3changeset_pk( /* ** CAPI3REF: Obtain old.* Values From A Changeset Iterator +** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator @@ -557,6 +606,7 @@ int sqlite3changeset_old( /* ** CAPI3REF: Obtain new.* Values From A Changeset Iterator +** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator @@ -590,6 +640,7 @@ int sqlite3changeset_new( /* ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator +** METHOD: sqlite3_changeset_iter ** ** This function should only be used with iterator objects passed to a ** conflict-handler callback by [sqlite3changeset_apply()] with either @@ -617,6 +668,7 @@ int sqlite3changeset_conflict( /* ** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations +** METHOD: sqlite3_changeset_iter ** ** This function may only be called with an iterator passed to an ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case @@ -633,6 +685,7 @@ int sqlite3changeset_fk_conflicts( /* ** CAPI3REF: Finalize A Changeset Iterator +** METHOD: sqlite3_changeset_iter ** ** This function is used to finalize an iterator allocated with ** [sqlite3changeset_start()]. @@ -649,6 +702,7 @@ int sqlite3changeset_fk_conflicts( ** to that error is returned by this function. Otherwise, SQLITE_OK is ** returned. This is to allow the following pattern (pseudo-code): ** +**
 **   sqlite3changeset_start();
 **   while( SQLITE_ROW==sqlite3changeset_next() ){
 **     // Do something with change.
@@ -657,6 +711,7 @@ int sqlite3changeset_fk_conflicts(
 **   if( rc!=SQLITE_OK ){
 **     // An error has occurred 
 **   }
+** 
*/ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); @@ -704,6 +759,7 @@ int sqlite3changeset_invert( ** sqlite3_changegroup object. Calling it produces similar results as the ** following code fragment: ** +**
 **   sqlite3_changegroup *pGrp;
 **   rc = sqlite3_changegroup_new(&pGrp);
 **   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
@@ -714,6 +770,7 @@ int sqlite3changeset_invert(
 **     *ppOut = 0;
 **     *pnOut = 0;
 **   }
+** 
** ** Refer to the sqlite3_changegroup documentation below for details. */ @@ -729,11 +786,15 @@ int sqlite3changeset_concat( /* ** CAPI3REF: Changegroup Handle +** +** A changegroup is an object used to combine two or more +** [changesets] or [patchsets] */ typedef struct sqlite3_changegroup sqlite3_changegroup; /* ** CAPI3REF: Create A New Changegroup Object +** CONSTRUCTOR: sqlite3_changegroup ** ** An sqlite3_changegroup object is used to combine two or more changesets ** (or patchsets) into a single changeset (or patchset). A single changegroup @@ -771,6 +832,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); /* ** CAPI3REF: Add A Changeset To A Changegroup +** METHOD: sqlite3_changegroup ** ** Add all changes within the changeset (or patchset) in buffer pData (size ** nData bytes) to the changegroup. @@ -848,6 +910,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); /* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup +** METHOD: sqlite3_changegroup ** ** Obtain a buffer containing a changeset (or patchset) representing the ** current contents of the changegroup. If the inputs to the changegroup @@ -878,25 +941,25 @@ int sqlite3changegroup_output( /* ** CAPI3REF: Delete A Changegroup Object +** DESTRUCTOR: sqlite3_changegroup */ void sqlite3changegroup_delete(sqlite3_changegroup*); /* ** CAPI3REF: Apply A Changeset To A Database ** -** Apply a changeset to a database. This function attempts to update the -** "main" database attached to handle db with the changes found in the -** changeset passed via the second and third arguments. +** Apply a changeset or patchset to a database. These functions attempt to +** update the "main" database attached to handle db with the changes found in +** the changeset passed via the second and third arguments. ** -** The fourth argument (xFilter) passed to this function is the "filter +** The fourth argument (xFilter) passed to these functions is the "filter ** callback". If it is not NULL, then for each table affected by at least one ** change in the changeset, the filter callback is invoked with ** the table name as the second argument, and a copy of the context pointer -** passed as the sixth argument to this function as the first. If the "filter -** callback" returns zero, then no attempt is made to apply any changes to -** the table. Otherwise, if the return value is non-zero or the xFilter -** argument to this function is NULL, all changes related to the table are -** attempted. +** passed as the sixth argument as the first. If the "filter callback" +** returns zero, then no attempt is made to apply any changes to the table. +** Otherwise, if the return value is non-zero or the xFilter argument to +** is NULL, all changes related to the table are attempted. ** ** For each table that is not excluded by the filter callback, this function ** tests that the target database contains a compatible table. A table is @@ -941,7 +1004,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** **
**
DELETE Changes
-** For each DELETE change, this function checks if the target database +** For each DELETE change, the function checks if the target database ** contains a row with the same primary key value (or values) as the ** original row values stored in the changeset. If it does, and the values ** stored in all non-primary key columns also match the values stored in @@ -986,7 +1049,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** [SQLITE_CHANGESET_REPLACE]. ** **
UPDATE Changes
-** For each UPDATE change, this function checks if the target database +** For each UPDATE change, the function checks if the target database ** contains a row with the same primary key value (or values) as the ** original row values stored in the changeset. If it does, and the values ** stored in all modified non-primary key columns also match the values @@ -1017,11 +1080,28 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** This can be used to further customize the applications conflict ** resolution strategy. ** -** All changes made by this function are enclosed in a savepoint transaction. +** All changes made by these functions are enclosed in a savepoint transaction. ** If any other error (aside from a constraint failure when attempting to ** write to the target database) occurs, then the savepoint transaction is ** rolled back, restoring the target database to its original state, and an ** SQLite error code returned. +** +** If the output parameters (ppRebase) and (pnRebase) are non-NULL and +** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2() +** may set (*ppRebase) to point to a "rebase" that may be used with the +** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) +** is set to the size of the buffer in bytes. It is the responsibility of the +** caller to eventually free any such buffer using sqlite3_free(). The buffer +** is only allocated and populated if one or more conflicts were encountered +** while applying the patchset. See comments surrounding the sqlite3_rebaser +** APIs for further details. +** +** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent +** may be modified by passing a combination of +** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter. +** +** Note that the sqlite3changeset_apply_v2() API is still experimental +** and therefore subject to change. */ int sqlite3changeset_apply( sqlite3 *db, /* Apply change to "main" db of this handle */ @@ -1038,6 +1118,41 @@ int sqlite3changeset_apply( ), void *pCtx /* First argument passed to xConflict */ ); +int sqlite3changeset_apply_v2( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, /* OUT: Rebase data */ + int flags /* Combination of SESSION_APPLY_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3changeset_apply_v2 +** +** The following flags may passed via the 9th parameter to +** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]: +** +**
+**
SQLITE_CHANGESETAPPLY_NOSAVEPOINT
+** Usually, the sessions module encloses all operations performed by +** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The +** SAVEPOINT is committed if the changeset or patchset is successfully +** applied, or rolled back if an error occurs. Specifying this flag +** causes the sessions module to omit this savepoint. In this case, if the +** caller has an open transaction or savepoint when apply_v2() is called, +** it may revert the partially applied changeset by rolling it back. +*/ +#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -1135,6 +1250,161 @@ int sqlite3changeset_apply( #define SQLITE_CHANGESET_REPLACE 1 #define SQLITE_CHANGESET_ABORT 2 +/* +** CAPI3REF: Rebasing changesets +** EXPERIMENTAL +** +** Suppose there is a site hosting a database in state S0. And that +** modifications are made that move that database to state S1 and a +** changeset recorded (the "local" changeset). Then, a changeset based +** on S0 is received from another site (the "remote" changeset) and +** applied to the database. The database is then in state +** (S1+"remote"), where the exact state depends on any conflict +** resolution decisions (OMIT or REPLACE) made while applying "remote". +** Rebasing a changeset is to update it to take those conflict +** resolution decisions into account, so that the same conflicts +** do not have to be resolved elsewhere in the network. +** +** For example, if both the local and remote changesets contain an +** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)": +** +** local: INSERT INTO t1 VALUES(1, 'v1'); +** remote: INSERT INTO t1 VALUES(1, 'v2'); +** +** and the conflict resolution is REPLACE, then the INSERT change is +** removed from the local changeset (it was overridden). Or, if the +** conflict resolution was "OMIT", then the local changeset is modified +** to instead contain: +** +** UPDATE t1 SET b = 'v2' WHERE a=1; +** +** Changes within the local changeset are rebased as follows: +** +**
+**
Local INSERT
+** This may only conflict with a remote INSERT. If the conflict +** resolution was OMIT, then add an UPDATE change to the rebased +** changeset. Or, if the conflict resolution was REPLACE, add +** nothing to the rebased changeset. +** +**
Local DELETE
+** This may conflict with a remote UPDATE or DELETE. In both cases the +** only possible resolution is OMIT. If the remote operation was a +** DELETE, then add no change to the rebased changeset. If the remote +** operation was an UPDATE, then the old.* fields of change are updated +** to reflect the new.* values in the UPDATE. +** +**
Local UPDATE
+** This may conflict with a remote UPDATE or DELETE. If it conflicts +** with a DELETE, and the conflict resolution was OMIT, then the update +** is changed into an INSERT. Any undefined values in the new.* record +** from the update change are filled in using the old.* values from +** the conflicting DELETE. Or, if the conflict resolution was REPLACE, +** the UPDATE change is simply omitted from the rebased changeset. +** +** If conflict is with a remote UPDATE and the resolution is OMIT, then +** the old.* values are rebased using the new.* values in the remote +** change. Or, if the resolution is REPLACE, then the change is copied +** into the rebased changeset with updates to columns also updated by +** the conflicting remote UPDATE removed. If this means no columns would +** be updated, the change is omitted. +**
+** +** A local change may be rebased against multiple remote changes +** simultaneously. If a single key is modified by multiple remote +** changesets, they are combined as follows before the local changeset +** is rebased: +** +**
    +**
  • If there has been one or more REPLACE resolutions on a +** key, it is rebased according to a REPLACE. +** +**
  • If there have been no REPLACE resolutions on a key, then +** the local changeset is rebased according to the most recent +** of the OMIT resolutions. +**
+** +** Note that conflict resolutions from multiple remote changesets are +** combined on a per-field basis, not per-row. This means that in the +** case of multiple remote UPDATE operations, some fields of a single +** local change may be rebased for REPLACE while others are rebased for +** OMIT. +** +** In order to rebase a local changeset, the remote changeset must first +** be applied to the local database using sqlite3changeset_apply_v2() and +** the buffer of rebase information captured. Then: +** +**
    +**
  1. An sqlite3_rebaser object is created by calling +** sqlite3rebaser_create(). +**
  2. The new object is configured with the rebase buffer obtained from +** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure(). +** If the local changeset is to be rebased against multiple remote +** changesets, then sqlite3rebaser_configure() should be called +** multiple times, in the same order that the multiple +** sqlite3changeset_apply_v2() calls were made. +**
  3. Each local changeset is rebased by calling sqlite3rebaser_rebase(). +**
  4. The sqlite3_rebaser object is deleted by calling +** sqlite3rebaser_delete(). +**
+*/ +typedef struct sqlite3_rebaser sqlite3_rebaser; + +/* +** CAPI3REF: Create a changeset rebaser object. +** EXPERIMENTAL +** +** Allocate a new changeset rebaser object. If successful, set (*ppNew) to +** point to the new object and return SQLITE_OK. Otherwise, if an error +** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) +** to NULL. +*/ +int sqlite3rebaser_create(sqlite3_rebaser **ppNew); + +/* +** CAPI3REF: Configure a changeset rebaser object. +** EXPERIMENTAL +** +** Configure the changeset rebaser object to rebase changesets according +** to the conflict resolutions described by buffer pRebase (size nRebase +** bytes), which must have been obtained from a previous call to +** sqlite3changeset_apply_v2(). +*/ +int sqlite3rebaser_configure( + sqlite3_rebaser*, + int nRebase, const void *pRebase +); + +/* +** CAPI3REF: Rebase a changeset +** EXPERIMENTAL +** +** Argument pIn must point to a buffer containing a changeset nIn bytes +** in size. This function allocates and populates a buffer with a copy +** of the changeset rebased rebased according to the configuration of the +** rebaser object passed as the first argument. If successful, (*ppOut) +** is set to point to the new buffer containing the rebased changset and +** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the +** responsibility of the caller to eventually free the new buffer using +** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut) +** are set to zero and an SQLite error code returned. +*/ +int sqlite3rebaser_rebase( + sqlite3_rebaser*, + int nIn, const void *pIn, + int *pnOut, void **ppOut +); + +/* +** CAPI3REF: Delete a changeset rebaser object. +** EXPERIMENTAL +** +** Delete the changeset rebaser object and all associated resources. There +** should be one call to this function for each successful invocation +** of sqlite3rebaser_create(). +*/ +void sqlite3rebaser_delete(sqlite3_rebaser *p); + /* ** CAPI3REF: Streaming Versions of API functions. ** @@ -1143,12 +1413,13 @@ int sqlite3changeset_apply( ** ** ** -**
Streaming functionNon-streaming equivalent
sqlite3changeset_apply_str[sqlite3changeset_apply] -**
sqlite3changeset_concat_str[sqlite3changeset_concat] -**
sqlite3changeset_invert_str[sqlite3changeset_invert] -**
sqlite3changeset_start_str[sqlite3changeset_start] -**
sqlite3session_changeset_str[sqlite3session_changeset] -**
sqlite3session_patchset_str[sqlite3session_patchset] +**
sqlite3changeset_apply_strm[sqlite3changeset_apply] +**
sqlite3changeset_apply_strm_v2[sqlite3changeset_apply_v2] +**
sqlite3changeset_concat_strm[sqlite3changeset_concat] +**
sqlite3changeset_invert_strm[sqlite3changeset_invert] +**
sqlite3changeset_start_strm[sqlite3changeset_start] +**
sqlite3session_changeset_strm[sqlite3session_changeset] +**
sqlite3session_patchset_strm[sqlite3session_patchset] **
** ** Non-streaming functions that accept changesets (or patchsets) as input @@ -1239,6 +1510,23 @@ int sqlite3changeset_apply_strm( ), void *pCtx /* First argument passed to xConflict */ ); +int sqlite3changeset_apply_v2_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +); int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA, @@ -1276,6 +1564,13 @@ int sqlite3changegroup_output_strm(sqlite3_changegroup*, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); +int sqlite3rebaser_rebase_strm( + sqlite3_rebaser *pRebaser, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); /* diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 411354cc02..3b6c24fd11 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -14,6 +14,10 @@ # endif #endif +#ifndef SQLITE_AMALGAMATION + typedef unsigned char u8; +#endif + typedef struct TestSession TestSession; struct TestSession { sqlite3_session *pSession; @@ -711,10 +715,8 @@ static int testStreamInput( } -/* -** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? -*/ -static int SQLITE_TCLAPI test_sqlite3changeset_apply( +static int SQLITE_TCLAPI testSqlite3changesetApply( + int bV2, void * clientData, Tcl_Interp *interp, int objc, @@ -727,18 +729,36 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply( int nChangeset; /* Size of buffer aChangeset in bytes */ TestConflictHandler ctx; TestStreamInput sStr; + void *pRebase = 0; + int nRebase = 0; + int flags = 0; /* Flags for apply_v2() */ memset(&sStr, 0, sizeof(sStr)); sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); + /* Check for the -nosavepoint flag */ + if( bV2 && objc>1 ){ + const char *z1 = Tcl_GetString(objv[1]); + int n = strlen(z1); + if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){ + flags = SQLITE_CHANGESETAPPLY_NOSAVEPOINT; + objc--; + objv++; + } + } + if( objc!=4 && objc!=5 ){ - Tcl_WrongNumArgs(interp, 1, objv, - "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?" - ); + const char *zMsg; + if( bV2 ){ + zMsg = "?-nosavepoint? DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?"; + }else{ + zMsg = "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?"; + } + Tcl_WrongNumArgs(interp, 1, objv, zMsg); return TCL_ERROR; } if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) ){ - Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(objv[2]), 0); + Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(objv[1]), 0); return TCL_ERROR; } db = *(sqlite3 **)info.objClientData; @@ -748,24 +768,68 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply( ctx.interp = interp; if( sStr.nStream==0 ){ - rc = sqlite3changeset_apply(db, nChangeset, pChangeset, - (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx - ); + if( bV2==0 ){ + rc = sqlite3changeset_apply(db, nChangeset, pChangeset, + (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx + ); + }else{ + rc = sqlite3changeset_apply_v2(db, nChangeset, pChangeset, + (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx, + &pRebase, &nRebase, flags + ); + } }else{ sStr.aData = (unsigned char*)pChangeset; sStr.nData = nChangeset; - rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, - (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx - ); + if( bV2==0 ){ + rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, + (objc==5) ? test_filter_handler : 0, + test_conflict_handler, (void *)&ctx + ); + }else{ + rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr, + (objc==5) ? test_filter_handler : 0, + test_conflict_handler, (void *)&ctx, + &pRebase, &nRebase, flags + ); + } } if( rc!=SQLITE_OK ){ return test_session_error(interp, rc, 0); + }else{ + Tcl_ResetResult(interp); + if( bV2 && pRebase ){ + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pRebase, nRebase)); + } } - Tcl_ResetResult(interp); + sqlite3_free(pRebase); return TCL_OK; } +/* +** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? +*/ +static int SQLITE_TCLAPI test_sqlite3changeset_apply( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + return testSqlite3changesetApply(0, clientData, interp, objc, objv); +} +/* +** sqlite3changeset_apply_v2 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? +*/ +static int SQLITE_TCLAPI test_sqlite3changeset_apply_v2( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + return testSqlite3changesetApply(1, clientData, interp, objc, objv); +} + /* ** sqlite3changeset_apply_replace_all DB CHANGESET */ @@ -1019,6 +1083,125 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach( return TCL_OK; } +/* +** tclcmd: CMD configure REBASE-BLOB +** tclcmd: CMD rebase CHANGESET +** tclcmd: CMD delete +*/ +static int SQLITE_TCLAPI test_rebaser_cmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + struct RebaseSubcmd { + const char *zSub; + int nArg; + const char *zMsg; + int iSub; + } aSub[] = { + { "configure", 1, "REBASE-BLOB" }, /* 0 */ + { "delete", 0, "" }, /* 1 */ + { "rebase", 1, "CHANGESET" }, /* 2 */ + { 0 } + }; + + sqlite3_rebaser *p = (sqlite3_rebaser*)clientData; + int iSub; + int rc; + + if( objc<2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); + return TCL_ERROR; + } + rc = Tcl_GetIndexFromObjStruct(interp, + objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub + ); + if( rc!=TCL_OK ) return rc; + if( objc!=2+aSub[iSub].nArg ){ + Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg); + return TCL_ERROR; + } + + assert( iSub==0 || iSub==1 || iSub==2 ); + assert( rc==SQLITE_OK ); + switch( iSub ){ + case 0: { /* configure */ + int nRebase = 0; + unsigned char *pRebase = Tcl_GetByteArrayFromObj(objv[2], &nRebase); + rc = sqlite3rebaser_configure(p, nRebase, pRebase); + break; + } + + case 1: /* delete */ + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); + break; + + default: { /* rebase */ + TestStreamInput sStr; /* Input stream */ + TestSessionsBlob sOut; /* Output blob */ + + memset(&sStr, 0, sizeof(sStr)); + memset(&sOut, 0, sizeof(sOut)); + sStr.aData = Tcl_GetByteArrayFromObj(objv[2], &sStr.nData); + sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); + + if( sStr.nStream ){ + rc = sqlite3rebaser_rebase_strm(p, + testStreamInput, (void*)&sStr, + testStreamOutput, (void*)&sOut + ); + }else{ + rc = sqlite3rebaser_rebase(p, sStr.nData, sStr.aData, &sOut.n, &sOut.p); + } + + if( rc==SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(sOut.p, sOut.n)); + } + sqlite3_free(sOut.p); + break; + } + } + + if( rc!=SQLITE_OK ){ + return test_session_error(interp, rc, 0); + } + return TCL_OK; +} + +static void SQLITE_TCLAPI test_rebaser_del(void *clientData){ + sqlite3_rebaser *p = (sqlite3_rebaser*)clientData; + sqlite3rebaser_delete(p); +} + +/* +** tclcmd: sqlite3rebaser_create NAME +*/ +static int SQLITE_TCLAPI test_sqlite3rebaser_create( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + sqlite3_rebaser *pNew = 0; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "NAME"); + return SQLITE_ERROR; + } + + rc = sqlite3rebaser_create(&pNew); + if( rc!=SQLITE_OK ){ + return test_session_error(interp, rc, 0); + } + + Tcl_CreateObjCommand(interp, Tcl_GetString(objv[1]), test_rebaser_cmd, + (ClientData)pNew, test_rebaser_del + ); + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; +} + int TestSession_Init(Tcl_Interp *interp){ struct Cmd { const char *zCmd; @@ -1029,9 +1212,11 @@ int TestSession_Init(Tcl_Interp *interp){ { "sqlite3changeset_invert", test_sqlite3changeset_invert }, { "sqlite3changeset_concat", test_sqlite3changeset_concat }, { "sqlite3changeset_apply", test_sqlite3changeset_apply }, + { "sqlite3changeset_apply_v2", test_sqlite3changeset_apply_v2 }, { "sqlite3changeset_apply_replace_all", test_sqlite3changeset_apply_replace_all }, { "sql_exec_changeset", test_sql_exec_changeset }, + { "sqlite3rebaser_create", test_sqlite3rebaser_create }, }; int i; diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index a3d346c05c..a8ed01ae45 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -210,7 +210,7 @@ int sqlite3_user_authenticate( db->auth.nAuthPW = nPW; rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel); db->auth.authLevel = authLevel; - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); if( rc ){ return rc; /* OOM error, I/O error, etc. */ } diff --git a/main.mk b/main.mk index d3450a63cb..1df68076c1 100644 --- a/main.mk +++ b/main.mk @@ -55,7 +55,8 @@ THREADLIB += $(LIBS) LIBOBJ+= vdbe.o parse.o \ alter.o analyze.o attach.o auth.o \ backup.o bitvec.o btmutex.o btree.o build.o \ - callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o \ + callback.o complete.o ctime.o \ + date.o dbpage.o dbstat.o delete.o expr.o \ fault.o fkey.o \ fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \ fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \ @@ -64,17 +65,17 @@ LIBOBJ+= vdbe.o parse.o \ fts3_write.o fts5.o func.o global.o hash.o \ icu.o insert.o json1.o legacy.o loadext.o \ main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \ - memjournal.o \ + memdb.o memjournal.o \ mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \ notify.o opcodes.o os.o os_unix.o os_win.o \ pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \ random.o resolve.o rowset.o rtree.o \ select.o sqlite3rbu.o status.o stmt.o \ table.o threads.o tokenize.o treeview.o trigger.o \ - update.o userauth.o util.o vacuum.o \ + update.o upsert.o userauth.o util.o vacuum.o \ vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ vdbetrace.o wal.o walker.o where.o wherecode.o whereexpr.o \ - utf.o vtab.o + utf.o vtab.o window.o LIBOBJ += sqlite3session.o @@ -96,6 +97,7 @@ SRC = \ $(TOP)/src/complete.c \ $(TOP)/src/ctime.c \ $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ $(TOP)/src/dbstat.c \ $(TOP)/src/delete.c \ $(TOP)/src/expr.c \ @@ -116,6 +118,7 @@ SRC = \ $(TOP)/src/mem2.c \ $(TOP)/src/mem3.c \ $(TOP)/src/mem5.c \ + $(TOP)/src/memdb.c \ $(TOP)/src/memjournal.c \ $(TOP)/src/msvc.h \ $(TOP)/src/mutex.c \ @@ -146,7 +149,7 @@ SRC = \ $(TOP)/src/rowset.c \ $(TOP)/src/select.c \ $(TOP)/src/status.c \ - $(TOP)/src/shell.c \ + $(TOP)/src/shell.c.in \ $(TOP)/src/sqlite.h.in \ $(TOP)/src/sqlite3ext.h \ $(TOP)/src/sqliteInt.h \ @@ -159,6 +162,7 @@ SRC = \ $(TOP)/src/trigger.c \ $(TOP)/src/utf.c \ $(TOP)/src/update.c \ + $(TOP)/src/upsert.c \ $(TOP)/src/util.c \ $(TOP)/src/vacuum.c \ $(TOP)/src/vdbe.c \ @@ -178,7 +182,8 @@ SRC = \ $(TOP)/src/where.c \ $(TOP)/src/wherecode.c \ $(TOP)/src/whereexpr.c \ - $(TOP)/src/whereInt.h + $(TOP)/src/whereInt.h \ + $(TOP)/src/window.c # Source code for extensions # @@ -224,7 +229,8 @@ SRC += \ SRC += \ $(TOP)/ext/rtree/sqlite3rtree.h \ $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/rtree.c + $(TOP)/ext/rtree/rtree.c \ + $(TOP)/ext/rtree/geopoly.c SRC += \ $(TOP)/ext/session/sqlite3session.c \ $(TOP)/ext/session/sqlite3session.h @@ -261,6 +267,24 @@ FTS5_SRC = \ $(TOP)/ext/fts5/fts5_varint.c \ $(TOP)/ext/fts5/fts5_vocab.c \ +LSM1_SRC = \ + $(TOP)/ext/lsm1/lsm.h \ + $(TOP)/ext/lsm1/lsmInt.h \ + $(TOP)/ext/lsm1/lsm_ckpt.c \ + $(TOP)/ext/lsm1/lsm_file.c \ + $(TOP)/ext/lsm1/lsm_log.c \ + $(TOP)/ext/lsm1/lsm_main.c \ + $(TOP)/ext/lsm1/lsm_mem.c \ + $(TOP)/ext/lsm1/lsm_mutex.c \ + $(TOP)/ext/lsm1/lsm_shared.c \ + $(TOP)/ext/lsm1/lsm_sorted.c \ + $(TOP)/ext/lsm1/lsm_str.c \ + $(TOP)/ext/lsm1/lsm_tree.c \ + $(TOP)/ext/lsm1/lsm_unix.c \ + $(TOP)/ext/lsm1/lsm_varint.c \ + $(TOP)/ext/lsm1/lsm_vtab.c \ + $(TOP)/ext/lsm1/lsm_win32.c + # Generated source code files # @@ -270,12 +294,15 @@ SRC += \ opcodes.h \ parse.c \ parse.h \ + shell.c \ sqlite3.h # Source code to the test files. # TESTSRC = \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/test_expert.c \ $(TOP)/ext/fts3/fts3_term.c \ $(TOP)/ext/fts3/fts3_test.c \ $(TOP)/ext/rbu/test_rbu.c \ @@ -305,6 +332,7 @@ TESTSRC = \ $(TOP)/src/test_intarray.c \ $(TOP)/src/test_journal.c \ $(TOP)/src/test_malloc.c \ + $(TOP)/src/test_md5.c \ $(TOP)/src/test_multiplex.c \ $(TOP)/src/test_mutex.c \ $(TOP)/src/test_onefile.c \ @@ -317,10 +345,12 @@ TESTSRC = \ $(TOP)/src/test_sqllog.c \ $(TOP)/src/test_superlock.c \ $(TOP)/src/test_syscall.c \ + $(TOP)/src/test_tclsh.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_window.c \ $(TOP)/src/test_wsd.c # Extensions to be statically loaded. @@ -331,10 +361,13 @@ TESTSRC += \ $(TOP)/ext/misc/closure.c \ $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ + $(TOP)/ext/misc/explain.c \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/fuzzer.c \ $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/mmapwarm.c \ $(TOP)/ext/misc/nextchar.c \ + $(TOP)/ext/misc/normalize.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ $(TOP)/ext/misc/remember.c \ @@ -344,9 +377,10 @@ TESTSRC += \ $(TOP)/ext/misc/unionvtab.c \ $(TOP)/ext/misc/wholenumber.c \ $(TOP)/ext/misc/vfslog.c \ + $(TOP)/ext/misc/zipfile.c \ $(TOP)/ext/fts5/fts5_tcl.c \ $(TOP)/ext/fts5/fts5_test_mi.c \ - $(TOP)/ext/fts5/fts5_test_tok.c + $(TOP)/ext/fts5/fts5_test_tok.c #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c @@ -358,6 +392,7 @@ TESTSRC2 = \ $(TOP)/src/btree.c \ $(TOP)/src/build.c \ $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ $(TOP)/src/dbstat.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ @@ -394,6 +429,7 @@ TESTSRC2 = \ $(TOP)/ext/fts3/fts3_tokenizer.c \ $(TOP)/ext/fts3/fts3_write.c \ $(TOP)/ext/async/sqlite3async.c \ + $(TOP)/ext/misc/stmt.c \ $(TOP)/ext/session/sqlite3session.c \ $(TOP)/ext/session/test_session.c @@ -441,7 +477,8 @@ EXTHDR += \ $(TOP)/ext/fts3/fts3_hash.h \ $(TOP)/ext/fts3/fts3_tokenizer.h EXTHDR += \ - $(TOP)/ext/rtree/rtree.h + $(TOP)/ext/rtree/rtree.h \ + $(TOP)/ext/rtree/geopoly.c EXTHDR += \ $(TOP)/ext/icu/sqliteicu.h EXTHDR += \ @@ -457,8 +494,10 @@ TESTPROGS = \ testfixture$(EXE) \ sqlite3$(EXE) \ sqlite3_analyzer$(EXE) \ + sqlite3_checker$(EXE) \ sqldiff$(EXE) \ - dbhash$(EXE) + dbhash$(EXE) \ + sqltclsh$(EXE) # Databases containing fuzzer test cases # @@ -467,7 +506,8 @@ FUZZDATA = \ $(TOP)/test/fuzzdata2.db \ $(TOP)/test/fuzzdata3.db \ $(TOP)/test/fuzzdata4.db \ - $(TOP)/test/fuzzdata5.db + $(TOP)/test/fuzzdata5.db \ + $(TOP)/test/fuzzdata6.db # Standard options to testfixture # @@ -476,12 +516,18 @@ TESTOPTS = --verbose=file --output=test-out.txt # Extra compiler options for various shell tools # SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 +SHELL_OPT += -DSQLITE_ENABLE_RTREE SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB +SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB +SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB +SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC +SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 +FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000 DBFUZZ_OPT = KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ ST_OPT = -DSQLITE_THREADSAFE=0 @@ -495,9 +541,9 @@ libsqlite3.a: $(LIBOBJ) $(AR) libsqlite3.a $(LIBOBJ) $(RANLIB) libsqlite3.a -sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h +sqlite3$(EXE): shell.c libsqlite3.a sqlite3.h $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \ - $(TOP)/src/shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) + shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ @@ -536,6 +582,9 @@ ossshell$(EXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \ $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c $(TLIBS) $(THREADLIB) +sessionfuzz$(EXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h + $(TCC) -o sessionfuzz$(EXE) $(TOP)/test/sessionfuzz.c -lz $(TLIBS) $(THREADLIB) + mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TLIBS) $(THREADLIB) @@ -573,7 +622,7 @@ target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl tclsh $(TOP)/tool/mksqlite3c.tcl - cp tsrc/shell.c tsrc/sqlite3ext.h . + cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c cat sqlite3.c >>tclsqlite3.c @@ -606,6 +655,11 @@ lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o lemon $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . +# A tool to generate the source-id +# +mksourceid: $(TOP)/tool/mksourceid.c + $(BCC) -o mksourceid $(TOP)/tool/mksourceid.c + # Rules to build individual *.o files from generated *.c files. This # applies to: # @@ -645,13 +699,29 @@ parse.c: $(TOP)/src/parse.y lemon $(TOP)/tool/addopcodes.tcl mv parse.h parse.h.temp tclsh $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c ./mkkeywordhash >keywordhash.h +# Source files that go into making shell.c +SHELL_SRC = \ + $(TOP)/src/shell.c.in \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/shathree.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/completion.c \ + $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/sqlite3expert.h \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/src/test_windirent.c + +shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl + tclsh $(TOP)/tool/mkshellc.tcl >shell.c + # Rules to build the extension objects. @@ -741,6 +811,10 @@ fts5.c: $(FTS5_SRC) $(FTS5_HDR) tclsh $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . +lsm1.c: $(LSM1_SRC) + tclsh $(TOP)/ext/lsm1/tool/mklsm1c.tcl + cp $(TOP)/ext/lsm1/lsm.h . + userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c @@ -753,21 +827,40 @@ sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) # Rules for building test programs and for running tests # tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a - $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ + $(TCCX) $(TCL_FLAGS) -DTCLSH -o tclsqlite3 \ $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) -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){" >> $@ - echo "static const char *zMainloop = " >> $@ - tclsh $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@ - echo "; return zMainloop; }" >> $@ +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/sqlite3_analyzer.c.in $(TOP)/tool/mkccode.tcl + tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(EXE): sqlite3_analyzer.c $(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) +sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl + tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c + +sqltclsh$(EXE): sqltclsh.c + $(TCCX) $(TCL_FLAGS) sqltclsh.c -o $@ $(LIBTCL) $(THREADLIB) + +sqlite3_expert$(EXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c + $(TCCX) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert$(EXE) $(THREADLIB) + +CHECKER_DEPS =\ + $(TOP)/tool/mkccode.tcl \ + sqlite3.c \ + $(TOP)/src/tclsqlite.c \ + $(TOP)/ext/repair/sqlite3_checker.tcl \ + $(TOP)/ext/repair/checkindex.c \ + $(TOP)/ext/repair/checkfreelist.c \ + $(TOP)/ext/misc/btreeinfo.c \ + $(TOP)/ext/repair/sqlite3_checker.c.in + +sqlite3_checker.c: $(CHECKER_DEPS) + tclsh $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ + +sqlite3_checker$(TEXE): sqlite3_checker.c + $(TCCX) $(TCL_FLAGS) sqlite3_checker.c -o $@ $(LIBTCL) $(THREADLIB) + dbdump$(EXE): $(TOP)/ext/misc/dbdump.c sqlite3.o $(TCCX) -DDBDUMP_STANDALONE -o dbdump$(EXE) \ $(TOP)/ext/misc/dbdump.c sqlite3.o $(THREADLIB) @@ -779,21 +872,23 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB +TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c - $(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \ + $(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \ $(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \ -o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB) amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c \ $(TOP)/ext/session/test_session.c - $(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \ + $(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \ $(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \ $(TOP)/ext/session/test_session.c \ -o testfixture$(EXE) $(LIBTCL) $(THREADLIB) fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c - $(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \ + $(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \ -DSQLITE_ENABLE_FTS3=1 \ $(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \ -o testfixture$(EXE) $(LIBTCL) $(THREADLIB) @@ -810,14 +905,17 @@ fulltestonly: $(TESTPROGS) fuzztest queryplantest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS) -fuzztest: fuzzcheck$(EXE) $(FUZZDATA) +fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db ./fuzzcheck$(EXE) $(FUZZDATA) + ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db -fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA) +fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db ./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA) + ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db -valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) +valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) + valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db # The veryquick.test TCL tests. # @@ -888,6 +986,9 @@ showwal$(EXE): $(TOP)/tool/showwal.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showwal$(EXE) \ $(TOP)/tool/showwal.c sqlite3.o $(THREADLIB) +showshm$(EXE): $(TOP)/tool/showshm.c + $(TCC) -o showshm$(EXE) $(TOP)/tool/showshm.c + changeset$(EXE): $(TOP)/ext/session/changeset.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changeset$(EXE) \ $(TOP)/ext/session/changeset.c sqlite3.o $(THREADLIB) @@ -900,6 +1001,10 @@ rollback-test$(EXE): $(TOP)/tool/rollback-test.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o rollback-test$(EXE) \ $(TOP)/tool/rollback-test.c sqlite3.o $(THREADLIB) +atrc$(EXE): $(TOP)/test/atrc.c sqlite3.o + $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o atrc$(EXE) \ + $(TOP)/test/atrc.c sqlite3.o $(THREADLIB) + LogEst$(EXE): $(TOP)/tool/logest.c sqlite3.h $(TCC) -o LogEst$(EXE) $(TOP)/tool/logest.c @@ -973,9 +1078,12 @@ clean: rm -f sqlite3rc.h rm -f shell.c sqlite3ext.h rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c + rm -f sqlite3_expert sqlite3_expert.exe rm -f sqlite-*-output.vsix rm -f mptester mptester.exe rm -f fuzzershell fuzzershell.exe rm -f fuzzcheck fuzzcheck.exe + rm -f sessionfuzz rm -f sqldiff sqldiff.exe rm -f fts5.* fts5parse.* + rm -f lsm.h lsm1.c diff --git a/manifest b/manifest index 29e51aef83..c45274c153 100644 --- a/manifest +++ b/manifest @@ -1,20 +1,23 @@ -C Add\sexperimental\ssqlite3_open_v2()\sflag\sSQLITE_OPEN_REUSE_SCHEMA.\sFor\ssharing\nidentical\sin-memory\sschema\sobjects\sbetween\sconnections. -D 2017-08-09T20:35:10.397 -F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 +C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. +D 2018-10-08T18:58:51.339 +F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 +F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea +F Makefile.in 01e95208a78b57d056131382c493c963518f36da4c42b12a97eb324401b3a334 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 -F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd -F VERSION f81232df28e2d3ff049feefad5fbd5489cc33697f6bd2ecf61af7f0dde3b83d0 +F Makefile.msc b946f8806a5d401a299453f61de80dfd1a9df14fa4902b299e6465e3c3134872 +F README.md 377233394b905d3b2e2b33741289e093bc93f2e7adbe00923b2c5958c9a9edee +F VERSION 654da1d4053fb09ffc33a3910e6d427182a7dcdc67e934fa83de2849ac83fccb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 -F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc b77aec100e4fb4739748a2461b5aa82c179fcde35bc0e08ce52ae7322d218701 +F autoconf/Makefile.am e14b629addaa1ce372b72043f28f40de2e32b7e211b6e0fc18dbb87989197e40 +F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac +F autoconf/Makefile.msc 9e73d9abaadb7a4951ddd0e947c5c791770f23bb1e04bfa50b43c01bee0575f2 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac 2893b823ecc86cea13739f6c8109a41392254d1db08235c5615e0af5722c8578 +F autoconf/configure.ac 308de24343e76ecfbe9a67f8fcd4c5216b790d230c5d9ce10210b7d5965d6192 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -30,16 +33,23 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 2500b432572804093c9a2516e2b16dbcec5d797ea1cd654915cfecd1d7a39ee3 x -F configure.ac 13f45f02e6c51dd0e347315b5401c3f047712b7f79b7f35619115c23755afcff +F configure 5811ffcd4866902d1706dcf8e0527f89165ec52859659942c9649bb1d3e4cc7b x +F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad -F doc/lemon.html 1f8b8d4c9f5cfe40e679fee279cc9eb2da8e6eb74ad406028538d7864cc4b6cb +F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd +F doc/lemon.html ac63db056bce24b7368e29319cd1a7eb5f1798cc85922d96a80b6c3a4ff9f51b F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74 F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef +F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 +F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 +F ext/expert/expert1.test 333d037021c901322f9afc4a5687648ea23d56f1a0a079358a390664babf01be +F ext/expert/sqlite3expert.c 89b7b59be610b929958db02416539a46ac088fd84f81623c4190aff62e92c3c4 +F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811 +F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea @@ -70,11 +80,11 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c f1c58503bc81c3dab1a70b25e146878ae40fccc716fd7c9b817995b661bc896f +F ext/fts3/fts3.c 53020b61dac31c167668f098ec83c0387ecd65b9e89ba3659f2f8d3e76efdf1e F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a +F ext/fts3/fts3Int.h 3378157f383540857a466420b8279626204434c3eb0dc948ad9bcd3991fc41f5 F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 -F ext/fts3/fts3_expr.c dfd571a24412779ac01f25c01d888c6ef7b2d0ef +F ext/fts3/fts3_expr.c 3b1dbceddd8622599f3cc2626897667fe40487aaa1676707d6c37ec5a8422fc1 F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652 @@ -88,42 +98,42 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 525a3bd9a7564603c5c061b7de55403a565307758a94600e8a2f6b00d1c40d9d F ext/fts3/fts3_unicode2.c cc04fc672bfd42b1e650398cb0bf71f64f9aae032cfe75bbcfe75b9cf966029c -F ext/fts3/fts3_write.c a3f7bf869622d1d0aa66661ba71d88e6f9646d69a2c335f40a0addf25974db47 +F ext/fts3/fts3_write.c b583dede85eb0c3c3026f8d7ccb781ea4e845ae583754fecb2ca425b5907d87d F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677 F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 -F ext/fts3/unicode/mkunicode.tcl ab0543a3b2399092ea2dd75df1bef333405b0d7f6b8c4951a0fbb60e780cb69f -F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 +F ext/fts3/unicode/mkunicode.tcl 0069320b64db6ee269c5e95f1f150d070fbf0a863fc7b3549d7e52bd068fb118 +F ext/fts3/unicode/parseunicode.tcl 024ae0bdd96309d7b8fc479148191e9b3001dc74017a3f65f9a27de3b3ff968b F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 -F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 -F ext/fts5/fts5Int.h 15e7514b46a845937d7c62e5c69e935091f0dbb72eb61aa4c8bcfbd39fdea158 -F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 +F ext/fts5/fts5.h 5edc74ca603d71284d475886e6e91b5c5cf2e8e93e9ba3a36ba2f2440ee97948 +F ext/fts5/fts5Int.h 39f12034b598df4e0f59bbe6cf03af03a905a534b04f182d155641a04e1eb797 +F ext/fts5/fts5_aux.c ca666a3bbe07c5a3bbe9fffaea19c935a1efaf337333e28bad7bdd1971ffd093 F ext/fts5/fts5_buffer.c 1dd1ec0446b3acfc2d7d407eb894762a461613e2695273f48e449bfd13e973ff F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c f2825f714d91bbe62ab5820aee9ad12e0c94205b2a01725eaa9072415ae9ff1c +F ext/fts5/fts5_expr.c 5aef080ba3c8947e22f38ce1ff9fe548e4a740e72b77241f35ed941ae128d2c7 F ext/fts5/fts5_hash.c 32be400cf761868c9db33efe81a06eb19a17c5402ad477ee9efb51301546dd55 -F ext/fts5/fts5_index.c 2ce9d50ec5508b8205615aad69e1c9b2c77f017f21d4479e1fb2079c01fdd017 -F ext/fts5/fts5_main.c 24868f88ab2a865defbba7a92eebeb726cc991eb092b71b5f5508f180c72605b -F ext/fts5/fts5_storage.c fb5ef3c27073f67ade2e1bea08405f9e43f68f5f3676ed0ab7013bce5ba10be6 -F ext/fts5/fts5_tcl.c a7df39442ae674dde877cf06fe02ebb7658e69c179a4d223241c90df4f14b54e +F ext/fts5/fts5_index.c d1b2d7d92cb2b72b9465da35b7d7c30e4b426c7f208bf6f94ce86b50eed8a1cb +F ext/fts5/fts5_main.c 7e52868e6b444e5353ff30e1dcd2a9273e8eaa543ddccf0c94b3cd2c235ff104 +F ext/fts5/fts5_storage.c 4bec8a1b3905978b22a67bca5f4a3cfdb94af234cf51efb36f4f2d733d278634 +F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 65864ba1e5c34a61d409c4c587e0bbe0466eb4f8f478d85dc42a92caad1338e6 F ext/fts5/fts5_test_tok.c ffd657dd67e7fcdb31bf63fb60b6d867299a581d0f46e97086abacd66c2a9b26 -F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 -F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf +F ext/fts5/fts5_tokenize.c ebd13d034f3dc7c841e1c32c364a4fca5cc2e05a0b91682a93fa1e6defcd4292 +F ext/fts5/fts5_unicode2.c 543cf0987c27ad59e5a7a6222480b917b5431009b7b139027c9581a63e39e37e F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738 -F ext/fts5/fts5_vocab.c e44fefa7f0c1db252998af071daf06a7147e17e7 -F ext/fts5/fts5parse.y a070b538e08ae9e2177d15c337ed2a3464408f0f886e746307098f746efd94ca +F ext/fts5/fts5_vocab.c 1cd79854cb21543e66507b25b0578bc1b20aa6a1349b7feceb8e8fed0e7a77a6 +F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 -F ext/fts5/test/fts5aa.test cba3fae6466446980caf1b9f5f26df77f95a999d35db7d932d6e82ae7ba0ede9 +F ext/fts5/test/fts5aa.test 87f4b50e755b52c6192c76ceccf4247d462bb44b52fa17358f273d8ce5d975f0 F ext/fts5/test/fts5ab.test 9205c839332c908aaad2b01ab8670ece8b161e8f2ec8a9fabf18ca9385880bb7 F ext/fts5/test/fts5ac.test a7aa7e1fefc6e1918aa4d3111d5c44a09177168e962c5fd2cca9620de8a7ed6d F ext/fts5/test/fts5ad.test e8cf959dfcd57c8e46d6f5f25665686f3b6627130a9a981371dafdf6482790de F ext/fts5/test/fts5ae.test 1142d16d9cc193894dc13cc8f9c7a8a21411ac61b5567a878514df6f9f0d7bb7 -F ext/fts5/test/fts5af.test aa635947bda31ac87fbe99483eef4d9a8571f58ad89c75dfb63312a35688eceb +F ext/fts5/test/fts5af.test 724247405b13f8f06cc6ce464dc4f152dc5dd4e86b12c2099685d8f19747bf7b F ext/fts5/test/fts5ag.test 7816f25a0707578f08145ab539fc0ca025f8951e788b28a6a18a06b2099469dd F ext/fts5/test/fts5ah.test 27b5a33bfd0363ca8a4dc659e6e2a5df3dea1c3c5b04bc51ca6aeb1277bd9b21 F ext/fts5/test/fts5ai.test d837c42249c0d8ad1a2912270e22cf2f303790a611f85c0be3a58e42a3696e3d @@ -136,10 +146,12 @@ F ext/fts5/test/fts5aux.test 8e7f9c96f8570f48402f2fd7b74e1ccfadd319fa56ef6773218 F ext/fts5/test/fts5auxdata.test eacc97ff04892f1a5f3d4df5a73f8bcbc3955ea1d12c9f24137eb1fc079e7611 F ext/fts5/test/fts5bigpl.test 6466c89b38439f0aba26ac09e232a6b963f29b1cbe1304f6a664fe1e7a8f5fd3 F ext/fts5/test/fts5bigtok.test 541119e616c637caea925a8c028c37c2c29e94383e00aa2f9198d530724b6e36 +F ext/fts5/test/fts5cat.test daba0b80659460b0cb60bd1f40b402478a761fe7ea414c3c94c2be25568cc33a F ext/fts5/test/fts5colset.test a30473451321bbf0b6218af62e96b4ae5fa99931cfdb210b5ecc804623b30f75 F ext/fts5/test/fts5columnsize.test 45459ce4dd9fd853b6044cdc9674921bff89e3d840f348ca8c1630f9edbf5482 F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825ce437d26afe0817f F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d +F ext/fts5/test/fts5connect.test b12a2a8b02af3c31c18abbc33aa8100d364de19a888a44457484d21dbccb18a7 F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116 F ext/fts5/test/fts5corrupt.test 8957f0f7e57e0f8a102c5b6e1a7326d6a1966b28e1d99c5883822af1e6038e9e F ext/fts5/test/fts5corrupt2.test 6deaf9f9606b3c957529db9881622bb3a7829b19bb3cdf8f276f074d684ede56 @@ -156,13 +168,14 @@ F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421 F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522 F ext/fts5/test/fts5fault4.test 1c1db5fcfe59401e7833146100f1d8de284a0a686fac31ddac9fb56c459f725b F ext/fts5/test/fts5fault5.test a336e4e11847de24c9497f80cce18e00bb3fab7fb11f97d04eb9af898900a762 -F ext/fts5/test/fts5fault6.test 8a3c61402e36960ba46a419e73121fcefdc9160e0c04b6f5318c7fb0e3180dbc +F ext/fts5/test/fts5fault6.test a0fc0a8f99e4b16500c31dfc7e38e1defe0f1693ac47650517ac7b723b1956f8 F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd164090be139e9e97ed4c F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedaee42f148ff5105ee2 -F ext/fts5/test/fts5fault9.test 0111b229388bdf251b91cfead68580227801dd30960a19aa8fe9021a1e73cb6d +F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119 F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c -F ext/fts5/test/fts5faultB.test 28810d93d37b59ebd5cf9502897f4dc9e6adb8ea6a5f64e125d3088597199d0d +F ext/fts5/test/fts5faultB.test e6d04f9ea7b21be1d89abb8df2cb4baf65b0453b744d5a805fcd3ef45ff86a7e F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a +F ext/fts5/test/fts5first.test 707a591b1b7d893fcfcb2366cbfe56aefab5d9c7cfa58bef35eba73a1dbf3b29 F ext/fts5/test/fts5full.test 49b565da02918c06e58f51f0b953b0302b96f155aa68baba24782b81570685e2 F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e F ext/fts5/test/fts5hash.test a4cf51acad99bfc43c16fb74f9d22495dc221ae0701fc5e908ca963a9b26a02b @@ -177,12 +190,12 @@ F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c27 F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1 F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b -F ext/fts5/test/fts5plan.test e30e8378441114ef6977a3dc24ecd203caa670d782124dfc9a6e9af09f7abc4d +F ext/fts5/test/fts5plan.test 00dc4c974938b509db7cb3680407f068ee6e9cc824f492f68cb741a7b679fe41 F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15 F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457 F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056 -F ext/fts5/test/fts5query.test bdb6fd9e73268cfc07f789f1448cd71ea78acb02e481c619f286289ea18ca518 -F ext/fts5/test/fts5rank.test 6e149da77a269923a8439aaa52366e49b85be4721902662da39a5ded16ed85d9 +F ext/fts5/test/fts5query.test ac363b17a442620bb0780e93c24f16a5f963dfe2f23dc85647b869efcfada728 +F ext/fts5/test/fts5rank.test beb1adae7b076beea98277f140e713f9713f503866d3ff7286c9805b220dd4a2 F ext/fts5/test/fts5rebuild.test 6d09fd54b1170a1e54fe17b808bbf17fba3154956cc2f065dd94bf1e3d254f63 F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415 F ext/fts5/test/fts5rowid.test 365997f5aebd619df3ae46c2a4bfc8edba361899bc4e52cebfba0dbcbf720522 @@ -194,26 +207,28 @@ F ext/fts5/test/fts5synonym2.test b54cce5c34ec08ed616f646635538ae82e34a0e28f947e F ext/fts5/test/fts5tok1.test ce6551e41ff56f30b69963577324624733bed0d1753589f06120d664d9cd45c9 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test 6aeb5e8061ffc0ff9a5299f27beaee3b2b4b8b336d4f107262bca338bea8f8e9 -F ext/fts5/test/fts5unicode.test 1e5570df758f7e0b27ff0e087ee96f559d5cc9ade80afa9421537a8a20a7cfbf +F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9 F ext/fts5/test/fts5unicode2.test 9b3df486de05fb4bde4aa7ee8de2e6dae1df6eb90e3f2e242c9383b95d314e3e F ext/fts5/test/fts5unicode3.test c3caecbe8264629ffe653b43ca5790b9793eba4422f92203e5247558e5a534e7 +F ext/fts5/test/fts5unicode4.test 6463301d669f963c83988017aa354108be0b947d325aef58d3abddf27147b687 F ext/fts5/test/fts5unindexed.test 9021af86a0fb9fc616f7a69a996db0116e7936d0db63892db6bafabbec21af4d F ext/fts5/test/fts5update.test 0737876e20e97a6a6abf45de19fc99315727bcee6a83fadcada1cc080b9aa8f0 F ext/fts5/test/fts5version.test 99b81372630fbf359107c96580fa761e41cdfb1dafc9966e148629ca72efee71 F ext/fts5/test/fts5vocab.test 2ba98bcef0fcab3e5fead8eaabd6c0efb7e57bfe707a5cfcc18572ca9b277360 +F ext/fts5/test/fts5vocab2.test 2beeec974a305a1d79b91426622cc922c87065874437d22b400de7438979959e F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59 F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c -F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 -F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332 +F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138 +F ext/icu/icu.c c2c7592574c08cd1270d909b8fb8797f6ea1f49e931e71dbcc25506b9b224580 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 -F ext/lsm1/Makefile 2951812df1c1cbc9e023af7e070876f479b3d75ce3898b3b9d00f83fecf13608 +F ext/lsm1/Makefile 98b0a24b45e248283d6bea4b6cb3e58d7b394edd8e96a0ac28c5fa5104813bad F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 -F ext/lsm1/lsm-test/lsmtest.h 5847594d4b43ec3412e1fd97104f7eb5fd770be55e691e6cb2e80929f86bebe3 -F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 +F ext/lsm1/lsm-test/lsmtest.h cf58528ffe0cfe535e91b44584e2ec5fb1caacdabecef0d8dcf83bf83168bf28 +F ext/lsm1/lsm-test/lsmtest1.c ae6ba48a0851b39be69a7d0eb220bfb9521a526e926223d5014bd385df10abb3 F ext/lsm1/lsm-test/lsmtest2.c 188b09aec776516aeedcfd13b9c6faf85ba16b3671a0897a2c740ee00a5dc4f8 F ext/lsm1/lsm-test/lsmtest3.c 9ab87528a36dbf4a61d7c8ad954f5ee368c0878c127b84b942b2e2abe522de26 F ext/lsm1/lsm-test/lsmtest4.c d258d6a245db5d8eaede096e2368d23f859c5e92c80ab9122463f708514fe10c @@ -228,66 +243,78 @@ F ext/lsm1/lsm-test/lsmtest_func.c 159aa401bc8032bfa3d8cf2977bd687abebab88025589 F ext/lsm1/lsm-test/lsmtest_io.c cf11b27b129c6bd5818fa1d440176502dc27229f0db892b4479118d61993ea20 F ext/lsm1/lsm-test/lsmtest_main.c a9bc647738c0dcaebf205d6d194b3ce4a6ef3925801cd2d919f0a4ea33a15aeb F ext/lsm1/lsm-test/lsmtest_mem.c 4e63c764345ab1df59d4f13a77980c6f3643798210b10d6cdbd785b4b888fda5 -F ext/lsm1/lsm-test/lsmtest_tdb.c 555fb101d2fe638abdd133e9294536c857fb38e0f227e049c00a67f51eaece06 +F ext/lsm1/lsm-test/lsmtest_tdb.c 618a8619183fda4f5540fcde15f9068293c5e3180e1a246e34409b0c148758b3 F ext/lsm1/lsm-test/lsmtest_tdb.h 8733eee249b12956a9df8322994b43d19bd8c02ad2e8b0bb5164db4d6ccc1735 F ext/lsm1/lsm-test/lsmtest_tdb2.cc 99ea7f2dd9c7536c8fb9bdd329e4cfeb76899f3ddf6f48bdd3926e016922b715 -F ext/lsm1/lsm-test/lsmtest_tdb3.c e44bf94e8bd724cd6ac161fd2cd44ffe43193932ad3a6bee1b07d80bb74012bb +F ext/lsm1/lsm-test/lsmtest_tdb3.c 7a7ccae189f5bb25bcd1ec3bbd740529706eded7f6729a5a0a9eeaeb57785320 F ext/lsm1/lsm-test/lsmtest_tdb4.c 47e8bb5eba266472d690fb8264f1855ebdba0ae5a0e541e35fcda61ebf1d277f F ext/lsm1/lsm-test/lsmtest_util.c 241622db5a332a09c8e6e7606b617d288a37b557f7d3bce0bb97809f67cc2806 F ext/lsm1/lsm-test/lsmtest_win32.c 0e0a224674c4d3170631c41b026b56c7e1672b151f5261e1b4cc19068641da2d F ext/lsm1/lsm.h 0f6f64ff071471cb87bf98beb8386566f30ea001 -F ext/lsm1/lsmInt.h e9e5c5f08e35a104086102b3def94ee69cbc0d39002f6596f5c80a640439628e -F ext/lsm1/lsm_ckpt.c ac6fb4581983291c2e0be6fbb68f12b26f0c08d606835c05417be1323d0fdd03 -F ext/lsm1/lsm_file.c e50f0e15427513dca4507110d0107268544bcaebb0ff0599a822da1f8d0da9eb +F ext/lsm1/lsmInt.h 5983690e05e83653cc01ba9d8fbf8455e534ddf8349ed9adedbf46a7549760b0 +F ext/lsm1/lsm_ckpt.c 0eabfaf812ddb4ea43add38f05e430694cd054eb622c3e35af4c43118a2d5321 +F ext/lsm1/lsm_file.c 3c51841d5b3e7da162693cbac9a9f47eeedf6bcbbe2969a4d25e30c428c9fe36 F ext/lsm1/lsm_log.c a8bf334532109bba05b09a504ee45fc393828b0d034ca61ab45e3940709d9a7c -F ext/lsm1/lsm_main.c 15e73ccdafdd44ddeefc29e332079d88ba8f00c12c797b3c2b63d3171b5afce8 +F ext/lsm1/lsm_main.c b5703f8042e71d3a2d65e671f6832e077e79e89e9975818f67f969922618db63 F ext/lsm1/lsm_mem.c 4c51ea9fa285ee6e35301b33491642d071740a0a F ext/lsm1/lsm_mutex.c 378edf0a2b142b4f7640ee982df06d50b98788ea -F ext/lsm1/lsm_shared.c 5bc37768e558492f60d7196735ddd54843cd239bd66c1af6eb205a6348ca5e46 -F ext/lsm1/lsm_sorted.c a04518dfbfff0171fafb152a46e9fe9f45e1edbf3570e4533dd58ddb6567f0c9 +F ext/lsm1/lsm_shared.c 76adfc1ed9ffebaf92746dde4b370ccc48143ca8b05b563816eadd2aadf1c525 +F ext/lsm1/lsm_sorted.c 6f7d8cf7a7d3d3f1ab5d9ba6347e8f39f3d73c00ec48afcd0c4bcbefd806f9b8 F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678bca82 F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c 43f954af668a66c7928b81597c14d6ad4be9fedbc276bbd80f52fa28a02fdb62 -F ext/lsm1/lsm_vtab.c 976ded75b78be59fc358cf5c06641cda01a4bd0b52374419ab36bf37f646d5df +F ext/lsm1/lsm_vtab.c 529255dc704289001b225d97e57e0cfa14b29c3f281c7349cfa8fdb655de79ae F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82 -F ext/lsm1/test/lsm1_simple.test 0ca15907fbfe09b6606f93149416786709e0cd55a69ecf53f605fadefa64228c -F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 +F ext/lsm1/test/lsm1_simple.test ca949efefa102f4644231dcd9291d8cda7699a4ce1006b26e0e3fcb72233f422 +F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0 +F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb +F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7 +F ext/misc/btreeinfo.c 78c8c57d325185ccc04b7679e5b020e34a4d9c87453e6b7ac943d0a26cee3256 F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005 -F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 -F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f -F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c b10ea114cf29f446e384064ae61e01373b431f6f172896f41ca0ba3507709003 -F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e -F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 -F ext/misc/fileio.c b1aa06c0f1dac277695d4529e5e976c65ab5678dcbb53a0304deaa8adc44b332 +F ext/misc/closure.c fe928228e8dfb2f00227311c203ccba9c2e5561f4f6de6da87e5b4a30cd8af15 +F ext/misc/completion.c fc811dda86d899c15848079c32cad40c181da1dd7a1a4f8d768a2c6ce07a1904 +F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 +F ext/misc/csv.c 65297bcce8d5acd5aadef42acbe739aef5a2ef5e74c7b73361ca19f3e21de657 +F ext/misc/dbdump.c 12389a10c410fadf1e68eeb382def92d5a7fa9ce7cce4fb86a736fa2bac1000a +F ext/misc/eval.c 6ea9b22a5fa0dd973b67ca4e53555be177bc0b7b263aadf1024429457c82c0e3 +F ext/misc/explain.c 5851a1a4a1bba6e078da4103fcafc84aa54adfd8edbba419f5cf1eba9f000d50 +F ext/misc/fileio.c 7317d825fab6a3c48f6e3822a00a6a22e08e55af31700ac96f16a523f83069fd F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984 -F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 +F ext/misc/json1.c 276f87dc8365b34b0fffb7ef32481dd07fac6fdb3224e2822396a48377ac8363 +F ext/misc/memstat.c 2780712e90765b810645227578438d972b76a089210901bfe9ec88f6a45b0570 +F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567 +F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 +F ext/misc/normalize.c b4290464f542bae7a97b43f15bd197949b833ffd668b7c313631bd5d4610212c F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c -F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb -F ext/misc/series.c b0f5f346aca9b7ff7caaf0da2efb4ad462441abd4dcd92a460cb573b3ea2370b -F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56 -F ext/misc/shathree.c fa185d7aee0ad0aca5e091b4a2db7baff11796170e5793b5de99e511a13af448 +F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77 +F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad +F ext/misc/series.c c7197db304f7009b08d6459a9de02e7f51ad0e1a3fdacbc1ebf5252a9a346959 +F ext/misc/sha1.c df0a667211baa2c0612d8486acbf6331b9f8633fd4d605c17c7cccd26d59c6bd +F ext/misc/shathree.c 22ba7ca84a433d6466a7d05dcc876910b435a715da8cc462517db9351412b8c8 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d +F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0f5e484 +F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74 F ext/misc/stmt.c 6f16443abb3551e3f5813bb13ba19a30e7032830015b0f92fe0c0453045c0a11 +F ext/misc/templatevtab.c 8251b31011dd00fc38e739c78c234c930be42b3b274bbe0493b79cd40db02a9e F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 -F ext/misc/unionvtab.c 1e0ebc5078e1a916db191bcd88f87e94ea7ba4aa563ee30ff706261cb4b39461 +F ext/misc/unionvtab.c 0b3173f69b8899da640a13a345dc5ef1400199405f738abe6145b2454195b8ff F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 +F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 -F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e -F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842 +F ext/misc/zipfile.c c4de8f0ad446ce4a49aae11ff7b771cd7af60d7136c0bcfb53da1475b9075e79 +F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 +F ext/rbu/rbu.c 8681f6157db6adc82c34af24b14ea8a3be0146ad2a3b6c1d5da6cb8a5796c8ce +F ext/rbu/rbu1.test 41123c64e8c88bd14eb7d3f8562f37fa87aaeb154b1eade2881de21d3504be55 F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702 F ext/rbu/rbu12.test bde22ed0004dd5d1888c72a84ae407e574aeae16 @@ -302,7 +329,8 @@ F ext/rbu/rbu9.test 0806d1772c9f4981774ff028de6656e4183082af F ext/rbu/rbuA.test 4e58e46e60d4064248614c43303d71f1b18cc804dd834ce6a913b3861828b28d F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 -F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead +F ext/rbu/rbu_common.tcl acfb7fbbaf8d46a9f6f6a5ec795616c84d705e1565d918afe43f0ff53ea0efa5 +F ext/rbu/rbucollate.test 86d6fc9b8f59a27b7b5a6e20b5e29816d338a0dbdea8c54bfcc549a0d437f3ea F ext/rbu/rbucrash.test 61470d977a06a0abc2ec35b05d82a1d7d87d10f4ffabad14c1c231edc942ad66 F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5 @@ -312,43 +340,61 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 0913c1aeaee266d9c36c33179341a5a504aad7d423d1979cfec43c8346a29899 F ext/rbu/rbufault4.test 34e70701cbec51571ffbd9fbf9d4e0f2ec495ca7 F ext/rbu/rbufts.test a2bbd202c9321fba15fb4a62a90add7d70e07bd8404e1e598135adbfff8a0508 +F ext/rbu/rbumulti.test 2cf153ab3d5861ff26517dc6cbaec430787a59f1d50e8771fe7a7529a0551cf1 F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 +F ext/rbu/rbusplit.test 69271c790732b28bd465551d80b0a9a3f074e189896ee8490ce56d22078c124d +F ext/rbu/rbutemplimit.test cd553a9288d515d0b5f87d277e76fd18c4aa740b761e7880fab11ce986ea18d1 F ext/rbu/rbuvacuum.test ff357e9b556ca7ad4673da0ff7f244def919ff858e0f9f350d3e30fdd83a62a8 F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa -F ext/rbu/sqlite3rbu.c 920941a6ff7dbbea0970717c43662878fda5c37e43752de329f0fdd76680ab75 -F ext/rbu/sqlite3rbu.h 82c102e5ae41025e3b245d3d5944315f82811da85e2cd363a75caa97cbd0cd3e -F ext/rbu/test_rbu.c ec18cfc69a104309df23c359e3c80306c9a6bdd1d2c53c8b70ae158e9832dcd6 +F ext/rbu/sqlite3rbu.c 71f8c09948d09ec9c5a8dbe7127e8ef61ef0853e698b2650be2485ac7b9c75c8 +F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2 +F ext/rbu/test_rbu.c baa23eb28457580673d2175e5f0c29ced0cd320ee819b13ad362398c53b96e90 +F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 +F ext/repair/checkfreelist.c 0dbae18c1b552f58d64f8969e4fb1e7f11930c60a8c2a9a8d50b7f15bdfd54bd +F ext/repair/checkindex.c 7d28c01a2e012ac64257d230fc452b2cafb78311a91a343633d01d95220f66f3 +F ext/repair/sqlite3_checker.c.in 4a5a3af3f450fe503e5a2985e98516dc2a6b9ad247449e284c1cf140fc91720f +F ext/repair/sqlite3_checker.tcl a9a2caa9660567257c177a91124d8c0dccdfa341e25c51e6da7f1fd9e601eafa +F ext/repair/test/README.md 34b2f542cf5be7bffe479242b33ee3492cea30711e447cc4a1a86cb5915f419e +F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc78249442da72ff3f8297398a69 +F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f +F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 4f1804b80ae06ddf7ff69192aacdceee283646dc6a328acb951f116147445212 -F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e -F ext/rtree/rtree1.test 4fdd60ae034e43f2fefc26492032d02e742e8b14d468b7c51d95a1e2fa47cf00 -F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba -F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482 -F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 -F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e -F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196 -F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971 -F ext/rtree/rtree8.test 076d9d5b783b61b7a23a5ab45fc899551dfffd821974f36ee599ff29f4de7a61 -F ext/rtree/rtree9.test 8bfa84dfaba1c897468a2448c28db0a00ad12d464225b5993c7814e907f3776f -F ext/rtree/rtreeA.test e25d76c1701f8591e7a0b6de8224d5dbc1418c562654c7240e6f33f37b1e36f7 -F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e -F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d +F ext/rtree/geopoly.c 9d8411b2bcaab719f65acc8a84d16200d5139ac634787df546c31bf9972b34e6 +F ext/rtree/rtree.c 6cc2e673cf1e9ea1619f13ab990f12389dfb951b131acbc2fbe164cee8992a20 +F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 +F ext/rtree/rtree1.test 309afc04d4287542b2cd74f933296832cc681c7b014d9405cb329b62053a5349 +F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2 +F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499 +F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b +F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142 +F ext/rtree/rtree6.test 593e0d36510d5ac1d1fb39b018274ff17604fe8fdca8cf1f8e16559cea1477f4 +F ext/rtree/rtree7.test c8fb2e555b128dd0f0bdb520c61380014f497f8a23c40f2e820acc9f9e4fdce5 +F ext/rtree/rtree8.test 924926d7c64ac59fcca0809de472d9dd73c612f54daae1cf992bdd7dac90305b +F ext/rtree/rtree9.test c646f12c8c1c68ef015c6c043d86a0c42488e2e68ed1bb1b0771a7ca246cbabf +F ext/rtree/rtreeA.test 20623ca337ca3bd7e008cc9fb49e44dbe97f1a80b238e10a12bb4afcd0da3776 +F ext/rtree/rtreeB.test 4cec297f8e5c588654bbf3c6ed0903f10612be8a2878055dd25faf8c71758bc9 +F ext/rtree/rtreeC.test 128928549d22b65c381ab1366760d08703cd75e34f6a7a506ece38f9330b7282 F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc -F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb -F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4 -F ext/rtree/rtreeG.test 3b185719630795f38594f64cd7d1de86a33f91f1 +F ext/rtree/rtreeE.test e65d3fc625da1800b412fc8785817327d43ccfec5f5973912d8c9e471928caa9 +F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd450ed331 +F ext/rtree/rtreeG.test 1b9ca6e3effb48f4161edaa463ddeaa8fca4b2526d084f9cbf5dbe4e0184939c +F ext/rtree/rtreeH.test aa08cc4fa8005b4c67446c7110205055b4d6da90e760e6f44b82dfa4cdf8d87a F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 -F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea +F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b587936f5f6bceed +F ext/rtree/rtreecheck.test 4d29103d1e16fcbf90135d1c637b833688492b063b2971dfb5dc6ba76555cfee +F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de +F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 +F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1d2f94ac66 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test 736d7ff178662f0b717c37f46531b84a5ce0210ccb0c4edf629c55dbcbbc3ea1 +F ext/session/session1.test 4532116484f525110eb4cfff7030c59354c0cde9def4d109466b0df2b35ad5cc F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 -F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8 +F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b @@ -356,27 +402,30 @@ F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 886252dcb7e692e62ef7e357456200912e367823 F ext/session/sessionC.test 97556f5164ac29f2344b24bd7de6a3a35a95c390 -F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 +F ext/session/sessionD.test d3617e29aa15c9413aee5286d99587633245d58d2ad28f3f331c822735418a22 F ext/session/sessionE.test 0a616c4ad8fd2c05f23217ebb6212ef80b7fef30f5f086a6633a081f93e84637 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce -F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 -F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73 +F ext/session/sessionG.test 3edde849c4071078d92bd682c836186f6e4e5a3fb6bcf3fc1de1a7caa5e4427d +F ext/session/sessionH.test 332b60e4c2e0a680105e11936201cabe378216f307e2747803cea56fa7d9ebae +F ext/session/session_common.tcl ee925e0d233677e45e395fb1f559b84068ce7baa8aa1034441739d3e87ee249c F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723 -F ext/session/sessionat.test feb7d22b3124882064b9d9df69f5484a9bb8c123dc9ddc6ffcd357521848139f +F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 -F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 +F ext/session/sessionfault2.test 555a8504de03d59b369ef20209585da5aeb2671dedabc4584e9ffe6269689185 +F ext/session/sessionrebase.test 4e1bcfd26fd8ed8ac571746f56cceeb45184f4d65490ea0d405227cfc8a9cba8 +F ext/session/sessionstat1.test 41cd97c2e48619a41cdf8ae749e1b25f34719de638689221aa43971be693bf4e F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc -F ext/session/sqlite3session.c cc127222a9ea6f4eaa31281aa9da924f5244f6099be0ee526c950684fb3513a6 -F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53 -F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 +F ext/session/sqlite3session.c ba76c7f01d4c71ab4d134cfda0ba43faae04bff01b8e81d1279a6101c706e3b5 +F ext/session/sqlite3session.h c01820d5b6e73e86d88008f4d1c1c7dfb83422963018292b864028a0400ceccf +F ext/session/test_session.c dba36c6c0153b22501112d3e8882b5c946cf617c955153b6712bd2f8ba1428c0 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 -F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f +F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e629edbe2648 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 5b7d72ab03dd70aa1401f934d31e85aefd6fc542eb58094d7a95d6921390b2d0 +F main.mk ff82d38126f8f0668b7990e0f1f3dcd74fa2d477c19b2e3feaaba586051e9b48 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -388,109 +437,111 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 748950c55b18099a82a9ee4da59272fa3ce935dc7edbdf22d3c84cbb56a31463 -F src/analyze.c a40d5a3012254c5d921a02a7c2eedf96118f541eb0a866dcdb6b6f2d64a03e43 -F src/attach.c 07b706e336fd3cedbd855e1f8266d10e82fecae07daf86717b5760cd7784c584 -F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c -F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b +F src/alter.c 59fa34093fdf62a4049f847c651216f8fc91da494f86cbea35207b115dc4e82c +F src/analyze.c 44f9189faccf08fbd547b3e232bec559f3669eeec3118751f26512e901698db5 +F src/attach.c 4bd5b92633671d3e8ce431153ebb1893b50335818423b5373f3f27969f79769a +F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df +F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 -F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 1a17ba1a765d80c3ca39ce33ff55f92e1f51eb84bbbdab5377f11d36b1515fa1 -F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca -F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 -F src/build.c 5b857c4302cb4b333beabfca7f4e79aa9705984cc77a3f09d2bd9cea4a58f855 -F src/callback.c cc17a561f8035b50e3ded141d1ceb582ae12cb79d879adcc43c6a3f28a698a57 +F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 +F src/btree.c 3f5e1a03db871e627bf5da21092bf7434ecfc5c5980bbd7d45eba13341340173 +F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2 +F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 +F src/build.c 9cc3ee9b5736ad53a2f1667e7e7bc69bcdacb6ed6419006b26421e969bc0b696 +F src/callback.c 83fb13418d563554316b0eea16cc53145ae8668884900eaa730fda398a7cc787 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 -F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74 -F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720 -F src/delete.c 939bd15e6b54b82b951e1c0ffc2ff2b4ab579196780a1f6d394e47bd6f799b6c -F src/expr.c fdb2fc465cabbf372fecad1fc2b291758bec74150b4db0fb945332e09df28a0e +F src/ctime.c b157b01081f92442f8b0218ddb93ddce8ebddad36dbddeecfdd771561dd4f387 +F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 +F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3 +F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91 +F src/delete.c 107e28d3ef8bd72fd11953374ca9107cd74e8b09c3ded076a6048742d26ce7d2 +F src/expr.c 5cee8fb79b1952689af80ed71ed16ad295f29d85de30c7592993b05cf1ec1e06 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333 -F src/func.c ed8888ae80b39f5a5d403954e4a05e0a38303523dff8143161439c142d31dec1 -F src/global.c 8a6ab6b4d91effb96ffa81b39f0d70c862abca157f8aaa194600a4a8b7923344 +F src/fkey.c 972a4ba14296bef2303a0abbad1e3d82bc3c61f9e6ce4e8e9528bdee68748812 +F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f +F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128 F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c d2d1bf12d2b5382450620d7cede84c7ffe57e6a89fa9a908f1aba68df2731cd9 +F src/insert.c 0a214201afec77880a31a59c33d86b473a160fc5cc31981eab2041ae03d8bf2f F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e -F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2 -F src/main.c bd53babb6dbe4df7e601b79bb1a9c1cc3ca0f135bc62f5151a2ebebc9ad6f5c4 -F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 +F src/loadext.c 30b140d0e5031924c56f802760506c0a235ced0dff9f3d95119aa86df12856e2 +F src/main.c 45b337a5e2cf6c3c87f509e620a45feb59258240135b1a72af28c689624a6eb8 +F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 +F src/memdb.c cb4013d56fa71c79c498717cbc47b27dd1c7653fd866584b2071ae04114eec46 F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661 F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81 -F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c +F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 -F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 -F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d +F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58 +F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235 F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 -F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 -F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 +F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de +F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c a361273749229755f92c8f0e3e4855054ad39bbc5c65773e8db5d0b79afa632c -F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223 +F src/os_unix.c d483d738183c822cc96ec5539424eee5b9847c882dee57f93b880aaf46a7af19 +F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 1e63b0299cf123cf38c48413ec03190f56c1e7d0ccc6573c467d8ac240b898e9 -F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 52ef3cecd0934e9da4a45b585883a03243ad615d338ad94f44501a05891dcdfa -F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 -F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 -F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa -F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2 -F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 -F src/prepare.c 955b618566c42ddb28a38bd80e804c477bc2eda5ebc474a1e152847a6013d38d -F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 +F src/pager.c a0d8f686ef64549ad5b356fd30429bd9ee7a06dd42b4d6faa096352ff26b1c5b +F src/pager.h ecc554a55bc55d1c4ba5e17137b72e238e00bd81e72ff2662d8b9c8c10ae3963 +F src/parse.y 6840fe7c0b5eb4dd25ee5d075213bc8255ed4c0678d71bfb6744d0520d91c179 +F src/pcache.c 4196eb6ed3bbf00b80596c8e0b4f50e57eb7d890c19fb27a7354306abb7f983d +F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170 +F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880 +F src/pragma.c a656ff043a03bd94153e6d731a3fbf1bb420207edc969d8fc04b4d2448387901 +F src/pragma.h 0ea639401ed7b8275c145e3a814119831e296118b545421e76ae2e1516f10ad8 +F src/prepare.c 051a2342f221f2c94b6bbbe4006b00546a3bf798f7c6ce8d4304ed9fcbcdad80 +F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 -F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 3fd19c98c5223d411b883502d1ac928ddb762a1ea8f031d910210316545fc67c -F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f -F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 -F src/sqlite.h.in e1574e78bfa86255774679106ac63e5a5ed732535930257acefd1855a0471e29 +F src/resolve.c bc8c79e56439b111e7d9415e44940951f7087e9466c3a9d664558ef0faf31073 +F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 +F src/select.c 33aacf1c17c64a00788c779b23d0875dd0d90eb4c08f867ebc31139ef3a67c95 +F src/shell.c.in 09342e09c9518e2d927566069272a7a47799e3ad4125562bbfc1240478c4a5a2 +F src/sqlite.h.in ced5a50faab700b4a60dd029a240496fa42e0225c9d5d381908c601d15fb27ee F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 -F src/sqliteInt.h 21a575b64a829fe1951030bab40135078ab0a152aea45535b2ad3057f31ee009 +F src/sqlite3ext.h 305adca1b5da4a33ce2db5bd236935768e951d5651bfe5560ed55cfcdbce6a63 +F src/sqliteInt.h cc1062f66d3827bf2ff53db306d1ddabc1f00be4e73adc9cc042678387d2def5 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b -F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 +F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c e117575fed5cef7c2dc60d53eb7003578c67aaf50bde9cc8e83ba876450a2ce5 -F src/test1.c 8513b17ca4a7a9ba28748535d178b6e472ec7394ae0eea53907f2d3bcdbab2df +F src/tclsqlite.c b15e46bdc1b14e994a358d51ce0bf8b7d7d4615cda96634ca0498ee39bc83b9c +F src/test1.c 9bb042e4afedc570f78638993fc9cc1760d897d3b27dd72c20618044b2a8fa5e F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 -F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b +F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d F src/test6.c e8d839fbc552ce044bec8234561a2d5b8819b48e29548ad0ba400471697946a8 F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010 -F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86 +F src/test8.c 3f7d0cc4e12e06832ba3db4455cb16867ccadafa602eb6ff5fcf097bffce56ed F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 -F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 +F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857 F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c abf6fc1fe9d041b699578c42e3db81f8831c4f5b804f1927958102ee8f2b773e +F src/test_config.c 3bbc5e593f308cbff426bb88c9dbf75deab551e5ddcece1251b8d9a40e55aef5 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2 F src/test_fs.c 35a2f7dd8a915900873386331386d9ba1ae1b5026d74fd20c2807bc76221f291 -F src/test_func.c a4fdab3363b436c1b12660e9362ce3f3782b7b5e +F src/test_func.c d12d805953bcb3bb19f71d29cdc93383b7b7a3369504d2b7e398a1bd77376294 F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766 +F src/test_malloc.c dec0aa821b230773aeb3dd11d652c1193f7cedb18a20b25659bc672288115242 +F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a @@ -505,66 +556,77 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c 11e6ce7575f489155c604ac4b439f2ac1d3d5aef F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939 -F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 +F src/test_tclsh.c 06317648b0d85a85fd823f7973b55535c59a3156c1ef59394fe511f932cfa78d +F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 -F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e +F src/test_vfs.c 112f1f9271c33c211812e0e681830a84262dac065da58579ff49f9cefec97d4f F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 -F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff -F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 +F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1 +F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215 +F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db5 -F src/treeview.c 2ee4a5dada213d5ab08a742af5c876cee6f1aaae65f10a61923f3fb63846afef -F src/trigger.c bda24e1772804abd4db550f60bc3be3ef2b09248589362163772b257054a9270 -F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc +F src/tokenize.c 9f55961518f77793edd56eee860ecf035d4370ebbb0726ad2f6cada6637fd16b +F src/treeview.c 0ef7dc77d6fe03172ba65dddfd3b3c557b7b7e217ca1963b7665beb266a0e2c0 +F src/trigger.c 9ec37388378ba50a433d3a2b7daaca5d712185977c0d3180ab5043c32ed4a8d0 +F src/update.c 1816d56c1bca1ba4e0ef98cac2f49be62858e9df1dc08844c7067eb41cc44274 +F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 -F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 -F src/vacuum.c c31a0fe4ca640e0aabf483bc2c65065b41622a3f6e820cd83817cce3e55a2581 -F src/vdbe.c 821b3edde2d17ec60da0617db1018a88f38634c359d22f3c8f7be10336c82636 -F src/vdbe.h 5aa766d2c95fd47a2d5d41e183ee052d21d3d8c3181c2255a56eac15aa6d62b4 -F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911 -F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc -F src/vdbeaux.c c30be9a7030f62418b3159a950702aff49839b43130f1ab25fc06b77261d76a7 -F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b -F src/vdbemem.c b7fac20534c79b7554dab2e8a180c585a8bc1b9c85149d1b2d9746cf314d06ed -F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e3 -F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 33ee6b2afdd43379b068e570fc88b8b8d4364ad02fcea5f3bc4d1d4dc0a33ae2 +F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 +F src/vacuum.c 6da236d4897c0227c0bef7c8f5be718482b65c8fc158fc46ffda2c529df1ba2f +F src/vdbe.c 005e691ea4c7d51e6c1a69d9389aeb34700884c85f51681817ddea3fdc2fc39b +F src/vdbe.h faedef405cf4e0679b46286576cebb307255d1a5c65908f470628255833faec4 +F src/vdbeInt.h f1f35f70460698d8f5a2bdef1001114babf318e2983a067804e2ae077d8e9827 +F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611 +F src/vdbeaux.c 40f4b3ca7e0b5328f72c7263aab49112e354ec6bdeb9f2aae8030bc029709306 +F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 +F src/vdbemem.c 81329ab760e4ec0162119d9cd10193e0303c45c5935bb20c7ae9139d44dd6641 +F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f +F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 +F src/vtab.c df409cbabcb98568981da6f3b6ae5465fc82da6f213bbdbb535a25714836b7e6 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 -F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 -F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a -F src/where.c cbe8ddffbcec7ce86f7a800fe8fd10aee412c76c87e0dd3732a1682e68d74cd9 -F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d -F src/wherecode.c e7be3b7f4c11908500cdf02b299d190d3742659533f58e0f4047962fdb5a48da -F src/whereexpr.c 1e55d79174522fe3b9b7ab224ebedc03da6ec5e6d204d740fa73e71280f54574 +F src/wal.c 3f4f653daf234fe713edbcbca3fec2350417d159d28801feabc702a22c4e213f +F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a +F src/walker.c fb94aadc9099ff9c6506d0a8b88d51266005bcaa265403f3d7caf732a562eb66 +F src/where.c a54a3d639bcd751d1474deff58e239b2e475a96e1b8f9178aa7864df8782a4e3 +F src/whereInt.h f125f29fca80890768e0b2caa14f95db74b2dacd3a122a168f97aa7b64d6968f +F src/wherecode.c 3df0a541373d5f999684d761e4bd700d57adb46c7d39da4e77b767b5adcd5893 +F src/whereexpr.c 1b5a5a7876997f65232bbf19c5c1eeb47eb328b8fa5b28c865543052904cde00 +F src/window.c a28d8d42c51c7e31136a42f3e245282049d4a9466b36d7bd765772991472df41 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 -F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 +F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 -F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783 -F test/alter.test b820ab9dcf85f8e3a65bc8326accb2f0c7be64ef +F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 +F test/alter.test 99e72759d48d6531ac2a9f346b4a9b5fe8f89c67a0fa5e916a3990d3b1fe9d09 F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060 F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3 -F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b -F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc +F test/alter4.test 7e93a21fe131e1dfeb317e90056856f96b10381fc7fe3a05e765569a23400433 +F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 +F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 +F test/altercol.test 53fb5e218c9296afc160f2c4fcbeaf42bd0604815d9b3896a7d2eec583ad8704 +F test/alterlegacy.test e7c07d605c2a85e7d1696c89e6bf64dfc932fc6d9320fe8708c8f5fc0b524d41 +F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 +F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b +F test/altertab.test fb8a9a2ab6deb5f860d27675f6213d14ab79b705e0d6350eead4ef3a3f73bf3e +F test/altertab2.test 159fd5f7b23ddc841fe678f579f9b1b8e69f44296f3ff75d1b4c155d37a59832 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f -F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321 -F test/analyze3.test 8b3ef8ba6d1096b76c40e0925c0fe51e700d2b779cdda40914580de3f9b9d80f -F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213 +F test/analyze.test b3a9c67d00e1df7588a5b7be9a0292899f94fe8cac1f94a017277474ca2e59df +F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8 +F test/analyze4.test cdf88f3f72b0f0643a1ff6c730fc5af1e42464d47478d9fbac84c333f72c014e F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 -F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f -F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f -F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82 -F test/analyze9.test b817b8e798315fc65b820a5463f73ad5f48ed8dd -F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a +F test/analyze6.test 7b2667b879976ac4b90d8df80d5456328684f1f6f6fdef9469d6e53401f2f469 +F test/analyze7.test a37f4d9cb699a8af068ae02df1bb08bf844df8e98a92a8126cbff89e226879d8 +F test/analyze8.test e32a970564271114786703750e6939cf81dea4b8580874e38e9213ee092f6936 +F test/analyze9.test 9fbf0e0101eef4f5dc149769aa14e10b76ee06e7c28598264b32173cd1999a54 +F test/analyzeA.test 22a892d67bd2223126335b99774cce56ba91122cfe82446d2927afc43ad667dc F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70 F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 -F test/analyzeD.test 42af58de25a6436502e43006e9e59e2d71bcb0cf +F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d -F test/analyzeF.test f423125b557f11ad71bb29765ef9c34b6dcf4ab7 +F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b @@ -573,24 +635,26 @@ F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061 +F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da +F test/atrc.c ec92d56d8fbed9eb3e11aaf1ab98cf7dd59e69dae31f128013f1d97e54e7dfed F test/attach.test f4b8918ba2f3e88e6883b8452340545f10a1388af808343c37fc5c577be8281c -F test/attach2.test 567047a7607aae8ebb3794642ebb168abe66b4af366fcd0cf7f616a1495cd43f +F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce F test/attach3.test c59d92791070c59272e00183b7353eeb94915976 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c -F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 -F test/auth.test 3d6cd8f3978ba55b1202574e6ecd79c6e00914ca44b9bfd6c1fe6fb873fcac88 +F test/attachmalloc.test 12c4f028e570acf9e0a4b0b7fe6f536e21f3d5ebddcece423603d0569beaf438 +F test/auth.test 3310d9c08e928beca42d3eadaaf53cef619d9d275f598565a3758a21ce63138e F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49 F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec -F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46 -F test/autoindex1.test 788d0894aa3aee1220036d20696e98733fb7ca02265cb1e801700177120c1aeb +F test/autoinc.test 9d202b7dce6571e52b744138eff12610214501acd635abdd72d18736cd06fd22 +F test/autoindex1.test a09958fa756129af10b6582bcbf3cbdf11e305e027b393f393caef801159dee0 F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df -F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 +F test/autoindex3.test 2dd997d6590438b53e4f715f9278aa91c9299cf3f81246a0915269c35beb790e F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf -F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990 +F test/autoindex5.test 5f0135dc3b266277b8c1904624439097d8e8020dd7197eda13fda23c35c21a05 F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 -F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 +F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989 F test/backup2.test 1fd1ad8c5b3d2d5b9c0cce4143a4fc610d51ddc6ae16a7a122973d43e6b50bbd @@ -601,14 +665,16 @@ F test/backup_malloc.test 0c9abdf74c51e7bedb66d504cd684f28d4bd4027 F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c -F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee -F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 -F test/bestindex3.test 578b6a52dab819e63f28e3640e04b32c85aed320 +F test/bestindex1.test 852170bddbb21daa121fabcc274640ff83d7d8705912e8b5fe7ed2c5a9a9224a +F test/bestindex2.test 9a0ccd320b6525eec3a706aae6cdab7e1b7b5abca75027e39f39f755e76e5928 +F test/bestindex3.test 001788a114ad96d81d5154fe77c7f1e26e84b3a2b5635ca29e4f96f6decc534e F test/bestindex4.test 4cb5ff7dbaebadb87d366f51969271778423b455 +F test/bestindex5.test 412b42f8036b28d8b2f3534d89389ad946a4b1a65a12263f51936f7424296f1b +F test/bestindex6.test d856a9bb63d927493575823eed44053bc36251e241aa364e54d0f2a2d302e1d4 F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc -F test/bigmmap.test ed6058a7794be26865c94d5bb62e12cdc4f7f01562b3b04f13eb3cdc52783921 +F test/bigmmap.test 31dad31573638bd32de866cdefd11843f75685be4ba6aec1a47918f098f1899b F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2 F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483 @@ -624,23 +690,23 @@ F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f -F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99 +F test/btree02.test a0f33669ba76632247c14718af32db939fa6de5cd13890798ad3f2a362cf7fe4 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 -F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 +F test/busy.test 510dc6daaad18bcbbc085bcc6217d6dc418def5e73f72ce1475eea0cb7834727 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9 -F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test 986e57cea8ab423b3fc8c2e3b69330394252d3d2a4496122ff3749e258305695 +F test/capi2.test 34a1a9a96d543a2ec2c209696b11b164444f57253b1f2cba1c2e53fadede6c7b +F test/capi3.test b299c89d80891c6c9b7f0e4b199df002b8b9f11c19f07d4a6eb7b325f1244de0 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test 7ebed1d8fa2f3190149d556fe8cff5a006be62af437c5c4640db614470126098 +F test/capi3c.test e853c6c1f9a596e0bc58153be08706813bf5795d479d6f81581e3bda3f9d0909 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe -F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 +F test/cast.test 5ceb920718d280b61163500a7d29e0e0a86458b1cbd92d96f962c9d970aa3857 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a F test/close.test 799ea4599d2f5704b0a30f477d17c2c760d8523fa5d0c8be4a7df2a8cad787d8 -F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 +F test/closure01.test 9905883f1b171a4638f98fc764879f154e214a306d3d8daf412a15e7f3a9b1e0 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846 F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621 @@ -654,14 +720,14 @@ F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 -F test/colname.test b111edd2a84f558567320904bb94c779d7eec47254265b5f0a3d1f3e52cc28e0 +F test/colname.test fb28b3687e03625425bc216edf8b186ce974aa71008e2aa1f426a7dcb75a601d F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9 F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97 -F test/corrupt2.test b6281ceadd6114d55e89b25e01c617af930dda71567f6a0996a719c385ac142e -F test/corrupt3.test e676f478fe602915d721472811f6f410b75ddc7e +F test/corrupt2.test fdfdffab9bc37d6d173f56ffb82472206f11dd4a68caad9360ac4db2eddb34c8 +F test/corrupt3.test f95d7bf78109e0b84eb285a787ce91a3fd6a2dd7d0cb55882abff3bdc081a57e F test/corrupt4.test 8d1d86b850fcc43e417450454f2044e52d55778a F test/corrupt5.test 8ead52af76006f3286e9396cb41898018ccea107 F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568 @@ -670,7 +736,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516 F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85 F test/corruptA.test 112f4b2ae0b95ebf3ea63718642fb969a93acea557ace3a307234d19c245989b F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec -F test/corruptC.test 46ec43bd90a02fd7b37ad8a7a949c55aa5717f89 +F test/corruptC.test 138ecb02188ed1a719b533d4a139568204039f72f00e07a8d30d920bd83122db F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62 F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 @@ -678,64 +744,67 @@ F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51 F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4 F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 -F test/corruptK.test 814a59ec699d8546b4e29005fba3d16e933ef2fe -F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8 +F test/corruptK.test 91550557849244a9904f4e090052e3f2c1c3f1106840d58b00ffaa3a8c2d3fc0 +F test/cost.test b37db8a10d467a69e71a9f3d40bbb266c2f587742b37c6912f6e3f7185a0e216 F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c -F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c +F test/countofview.test 2d0ce23daca1bada0522c3d62e0e0c0d69ec4e0fc41df2bcd662a5e11169b9c9 +F test/coveridxscan.test 5ec98719a2e2914e8908dc75f7247d9b54a26df04625f846ac7900d5483f7296 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418 F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc -F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219 +F test/crash5.test f14ff37eddc41991be4eb63568f86caa306fd9962a0ae3750db8836777bb7aae F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df -F test/crash8.test a63907617d8e74fb54b4bff23eca8a4435625245 +F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100 F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c -F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 +F test/csv01.test 6e1445b3207d574cff22fc41a8e549dfcf2466ee90546ada97d22a90fa89eb58 F test/ctime.test 78749e6c9a5f0010d67985be80788f841e3cd2da18114e2ed6010399a7d807f3 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 -F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b +F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f +F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e -F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 -F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab +F test/dbpage.test dbf50a4d361f9e45a979432c727506065113124478a7d2db12074fa655e65d6c +F test/dbstatus.test c15fa97f743dac7ce996814c84b56317e138895ee15ce27f15b608aa6924c90a +F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d -F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5 +F test/delete.test 31832b0c45ecb51a54348c68db173be462985901e6ed7f403d6d7a8f70ab4ef0 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86 -F test/delete_db.test c70a43629dd4d3e1dd03fdaf7a22153af6a69d92 +F test/delete_db.test 096d828493c7907f9ea11a7098ea6a0f73edba89406487d5d6cc2228dc4ab8b0 F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c -F test/distinct2.test faef8a3f27424e2cfbe19b2a40752294de3b5d957e049e3336be53ec0476cb58 +F test/distinct2.test df0bb52b754661ea84ec9ff488d48913c97bd31d83ca17ce0bf1334645e660cf F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05 F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145 F test/e_blobwrite.test f87ff598b67af5b3ec002a8d83e804dc8d23808e88cf0080c176612fc9ffce14 F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 -F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 +F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76d0df33b0a7 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5 -F test/e_expr.test 146deba180273d19e3bf9f6b45f4e50094c64c7ec4756ea72f79dda25818eb17 -F test/e_fkey.test dcdc6ad26b1d4f07636208de4c1c22aae7c0597a685a6c10fe6da91f3191dd96 +F test/e_expr.test ca8896601ade1e27c6559614c7f32c63d44636fdfa720436a160f09b8bf66c89 +F test/e_fkey.test 9778696ef9fceacebed8d482d02b47287981faaedf6f73db563ea8a7afb546da F test/e_fts3.test 8cf40550bb088a6aa187c818c00fabe26ef82900a4cd5c66b427ccafe28bedaa F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e F test/e_reindex.test 2bebf7b393e519198b7c654407221cf171a439b8 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 -F test/e_select.test 16651bb681e83a1a2875ff4a595ed2b4b4dee375 +F test/e_select.test c5a669b4d63217aa10094ba737ba3ddd07bd439d4bc7a5b798f6ea32511cbe7c F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 -F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519 +F test/e_uri.test 47eeb2960e74613f0f8722b2f13aef08fde69daa16e5380ac93df84dac8b1f72 F test/e_vacuum.test 1b8b4772d05374aa1b8958669138bbb4213ee26a F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625 F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 @@ -746,26 +815,26 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test 3f9ba0b2594837c7beaa3ba824e2137cfe857308f020ec5a0c7a62b444e837b0 +F test/eqp.test fc00ad1a7f5b90bf1bbccbf877ae9abef8bf5c7896174830d438c8f91a6ead88 F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c -F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9 +F test/exclusive.test 1206b87e192497d78c7f35552e86a9d05421498da300fb1cce5ca5351ccde3c3 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/expr.test 66a2c9ac34f74f036faa4092f5402c7d3162fc93 +F test/expr.test 7cb55e80aeb41d65fec968c08212505123063fea60bdc355d764d747670e9eea F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 -F test/fallocate.test 87b5e43c872b7e69cd80b7b8813eb102b571a75d45dda24e38b65537bcc85733 +F test/fallocate.test 07416bd593a116d5893cb244f45a94d5c6fe030561df3bd972e6135f8106e509 F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3 F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4 -F test/fkey1.test ba64806ff9a04eecab2679caad377ae99a5e94e4 -F test/fkey2.test 155809016fad6b2a1491facf2ac53a551bc57c2c +F test/fkey1.test d11dbb8a93ead9b5c46ae5d02da016d61245d47662fb2d844c99214f6163f768 +F test/fkey2.test 6206484a0eba570902a1a4d86489df24d0265f6994daebf851861d8f0cf4a27b F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0 -F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 +F test/fkey7.test 24076d43d3449f12f25503909ca4bfb5fc5fefd5af1f930723a496343eb28454 F test/fkey8.test e5372e32cdb4481f121ec3550703eeb7b4e0762c F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff @@ -807,7 +876,7 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654 F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0 -F test/fts3aa.test 39b65c11913d277c91d7426c62cfc1d147d1b4e9a48fecd9e38f60d0b5a5f505 +F test/fts3aa.test f267fcd6aca30fc70b81e5d82b68b34b38f581896020b57ed49e9777c7ebd85f F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63 F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49 @@ -821,15 +890,15 @@ F test/fts3ak.test bd14deafe9d1586e8e9bf032411026ac4f8c925d F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8 F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18 -F test/fts3ao.test c416d50c4fdb6f32a15205b3d0a49eb74fcea92feb66b531a83c904770de5ff1 +F test/fts3ao.test 266989148fec6d9f1bb6c5382f7aa3dcea0e9cd444576e28dd2b9287ac7dd220 F test/fts3atoken.test 4b4c16fdcfc972f2cdbba212375a060a86ccf5f1 F test/fts3auto.test b981fea19b132b4e6878f50d7c1f369b28f68eb9 -F test/fts3aux1.test 24b8a69e342a6684e3929408b245cdf5de0d45f8094108fa0a57cd007228963d +F test/fts3aux1.test 7a170e172afdbceb67f5baa05941fd4fbf56af42f61daa3d140f4b4bf4cb68f6 F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd491 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c -F test/fts3conf.test 60317efd562080e198b5bdc9fcd222ce32cf01d7 +F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f5a76b F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba F test/fts3corrupt3.test 56e0ee83e90b57f5f3644cb7d1b36a067b7b8b19cdf0dedce45e5e13cf752f65 @@ -840,15 +909,15 @@ F test/fts3defer2.test c540f5f5c2840f70c68fd9b597df817ec7170468 F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd F test/fts3drop.test 1b906e293d6773812587b3dc458cb9e8f3f0c297 F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851 -F test/fts3expr.test 9466627007804d855bf9df2a0cfb3dac23686fdc +F test/fts3expr.test ebae205a7a89446c32583bcd492dcb817b9f6b31819bb4dde2583bb99c77e526 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8 -F test/fts3expr4.test c39a15d676b14fc439d9bf845aa7bddcf4a74dc3 +F test/fts3expr4.test cac5dd815fe6b5921741abdccdde3b7f50b86394de91e13308ee7986859c4a9f F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49 F test/fts3fault.test 9fb7d6266a38806de841f7244bac1b0fe3a1477184bbb10b172d19d2ca6ad692 F test/fts3fault2.test 6a17a11d8034b1c4eca9f3091649273d56c49ff049e2173df8060f94341e9da0 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 -F test/fts3join.test 69aeb460d0ea17527a2b1b8d24ce18f29c7f207a7261867a2618f639c8020459 +F test/fts3join.test 949b4f5ae3ae9cc2423cb865d711e32476bdb205ab2be923fdf48246e4a44166 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test ce864e0bd92429df8008f31cf557269ba172482a F test/fts3misc.test ba03a83b831555cfd18c6c862b24b70a53ce7497fe55077f7c4b7c9ce83c2eed @@ -856,7 +925,8 @@ F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2 F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce -F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170 +F test/fts3query.test ca5dffabdfe9aef2ebcc89e02ce515898f86f8c30a365283831c53e0e08e5821 +F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3snippet.test 01a4231816e03a0660ae53ba2404fe69012fe0db @@ -878,38 +948,40 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309 -F test/fts4onepass.test 7319d61a2ed1325fc54afd0c060a0513b462303a +F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7 F test/fts4opt.test fd6a11684b965e1999564ae763797b7fb9e34c96 F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef +F test/func.test 09dda479bcfc568f99f3070413e9672a8eeedc1be9c5d819bf55d4788c2583b7 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4 +F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b -F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 2152602232c96d9c790eff3013e1369ce59de3203fa0b75bc613531448454e61 +F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 +F test/fuzzcheck.c 8074a35ed4ec3735a5e144b7e0e9123d9821a92281756c1a40d43e302dd79243 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 -F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 +F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba -F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21 -F test/fuzzdata5.db 9f0cdcc5c6e83b90cf9ae343bd07f684d2da2de7 +F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2 +F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 +F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/having.test b3d6b17cc9601b6b373b2d0f08c075ccf30e2d307249c3c8a236e3c36907b1a5 +F test/having.test e4098a4b8962f9596035c3b87a8928a10648acc509f1bb8d6f96413bbf79a1b3 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test dbc0b87756e1e20e7497b56889c9e9cd2f8cc2b5 +F test/hook.test 1604b3b2f5931430087540404555c1b6be3618600b81558657c66b533ed70b13 F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 -F test/icu.test 73956798bace8982909c00476b216714a6d0559a +F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test 2fa2dfba1afe30eb830f327e7131dfadaa7a701d677de0eb65f9303d99e18fe0 @@ -917,11 +989,12 @@ F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 F test/in5.test 7ae37fcd4a5e198291c6ab5f31a5bb3d15397efe8b75a6736d7a95a7b8dd9e08 +F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba -F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8 +F test/incrblob_err.test 89372a28f1d98254f03fed705f9efcd34ef61a674df16d2dbb4726944a2de5e9 F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758 F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a F test/incrvacuum.test b729aab1d4983037da57e66c20dfd7458561a85626dcf824f60175e35f4ce152 @@ -933,16 +1006,16 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7 -F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb +F test/index6.test d07ea75b8c21f125c6f325522e8df8c05c91e9251ec923a31d0582b2ba4a617d +F test/index7.test 72b59b8ddc5c13f4962886b4011eb9975014317d17ef36c6297921362fb7dd98 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 -F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 -F test/indexexpr1.test f348668daf7f533f1e5578dd4f31e4b9a3875da1ee2a60a8d2d50b938a7699c9 -F test/indexexpr2.test 3ddd7f23bc381b9f2b7a15f2d083b1a4078e7733dce8295602ecfa3c74a34cf9 +F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e +F test/indexexpr1.test 635261197bcdc19b9b2c59bbfa7227d525c00e9587faddb2d293c44d287ce60e +F test/indexexpr2.test d8f56b6cf4e5663486129bc18c6bde4cef9f8876942b001bfdd692a2b1a42668 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 -F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 +F test/insert.test 5604b1ff5675cc84c34a5b315792b958f48c32edccc0dafcc81d3b776270b70a F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 F test/insert4.test 46bead5f39e181850ee56adcf49d3a3157c460c52249211714612ac89fe34835 @@ -954,54 +1027,55 @@ F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc -F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d +F test/ioerr.test 470fcc78e9cd352d162baf782fe301ea807d764241f58a48fc58109c2dfcdb6b F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b -F test/join.test 442c462eea85cf065d70a663c626b780a95af6e11585d909bb63b87598afe678 -F test/join2.test a48f723c5692e2cbb23a9297ac2720cb77d51a70 +F test/istrue.test 62372ad3ddcc5d0eb8ff9097dcb0aad8961bf1b9cb45ba634f6e284695126f9a +F test/join.test 2ad9d7fe10e0cc06bc7803c22e5533be11cdadbc592f5f95d789a873b57a5a66 +F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 -F test/join5.test bc98ea4b4e5003f5b1453701ebb8cd7d1c01a550 +F test/join5.test 5a2da0c3ea852a7063d3e72fc7d5a04a6de5ef6e6d85092582f69033f7459adc F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b -F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577 +F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 -F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307 -F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa -F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d +F test/journal3.test c9c29883f5bf535ae82ae21c472df6263806a22e467b6db7cd0d6d545305b4f6 +F test/jrnlmode.test a6693f2bed4541a21e703aaa37bb3e10de154130645952933b82b2dec0a8b539 +F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/json101.test 2bd3703a8566e39f8efee8b83bb60aac363fa312e69c94b4024114e0fe77e380 +F test/json101.test b40a9f5395d8e669b0bc3eb550ad2ae9e5ada01fbce23c446c2a30a305a6d575 F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1 -F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 +F test/json103.test aff6b7a4c17d5a20b487a7bc1a274bfdc63b829413bdfb83bedac42ec7f67e3b F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c d2b8cfc91047ebf6cac4f3a04f19c3a864e4ecfd683bbb65c395df450b8dc79c +F test/kvtest.c 94da54bb66aae7a54e47cf7e4ea4acecc0f217560f79ad3abfcc0361d6d557ba F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 -F test/like.test 67d7431c9b664254febce9e90fd2f47c7c75c8b38444e2a50ef9ec2776b84ca8 +F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 +F test/like3.test 430691e6057e11a59e934be74c06b85605b80061d45af5714d52886a811efeb7 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e -F test/limit2.test e35f57bd3a62d7c5dcb5ac4306e675c75f974809 +F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 -F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12 +F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37b8 F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38 F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431 F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035 -F test/lookaside.test 90052e87282de256d613fcf8c9cbb845e4001d2f -F test/main.test bb75e406c9b64931f3dc7e7f04626633365bb22f +F test/lookaside.test 5a828e7256f1ee4da8e1bdaa03373a3ccdb0f1ff98dfa82e9b76cb41a45b1083 +F test/main.test 6bbb3999fd461eb8fb335cbab97409a3d7f91bbb8da60635e8be3e4a04a77772 F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 -F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8 -F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a +F test/malloc.test 18dd1c4188c81ca79cf123527c71b19ee0c31feb9947fdffb0dc6ceb1436816a +F test/malloc3.test 6e88bae6312854a4adb4ecc2a6a5ea8c59b4db778b724ba718e1c43fc8c3c136 F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 -F test/malloc5.test f6eb6eca07a4c75f2897bf43a404689b6295bb95ab2e07d4b52eda743f925a27 +F test/malloc5.test 2e4ad7684a13389a44a840499cd47173a8d05f22f082d7d083eece433a7a64eb F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d @@ -1017,70 +1091,78 @@ F test/mallocG.test 0ff91b65c50bdaba680fb75d87fe4ad35bb7934f F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb F test/mallocI.test 6c23a71df077fa5d387be90e7e669c5b368ca38a F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e -F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e +F test/mallocK.test 1f4b5efbf61715ab79b20b38739ff4b3d110ceb53f54e5db6da1f01c083707ab F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc F test/mallocM.test 78bbe9d3da84a5c679123cdb40d7b2010b18fc46e13897e4f253c6ba6fbff134 F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f +F test/malloctraceviewer.tcl b7a54595270c1d201abf1c3f3d461f27eaf24cdef623ad08a0fe5e411264c8a9 F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 +F test/memdb1.test 61aa1dbdeea6320791d2ff42a9a6149d5716be674bf06ee0ffa0aad1bf3eb5f8 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 6d268d0ae90f8d61a2356a1838665654d83de518 +F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41 -F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc +F test/minmax2.test dae92964ac87c1d2ef978c582e81a95e11c00f1cbef68980bfb2abaf10315063 F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f -F test/misc1.test 51ec3f56a2a7965de226964cff856695e743186826561536647f1e8b7d1d0eb3 +F test/misc1.test 704ea2cc7e7b9deb622b37953f0e77d0879826e8c3bfc1d7a691528035405061 F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3 F test/misc5.test 60e1fc758a93cacd19eb2fafcd1d40d150a05047546c7a92389c98047d621901 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 -F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2 -F test/misc8.test ba03aaa08f02d62fbb8d3b2f5595c1b33aa9bbc5 +F test/misc7.test 349855706310f0de6b91645d199f6874f518627fd057743fa4e3689b60d06efc +F test/misc8.test 8fb0f31d7a8aed484d759773ab8ad12ec746a477f4a67394a4af0e677494c3ca F test/misuse.test 9e7f78402005e833af71dcab32d048003869eca5abcaccc985d4f8dc1d86bcc7 -F test/mmap1.test d2cfc1635171c434dcff0ece2f1c8e0a658807ce +F test/mjournal.test 9d86e697dcbc5da2c4e8caba9b176b5765fe65e80c88c278b8c09a917e436795 +F test/mmap1.test fb04e0c10492455007624ade884ca0c8852ff3e4e11d95408f9709ca2ef7f626 F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93 F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3 +F test/mmapwarm.test 2272005969cd17a910077bd5082f70bc1fefad9a875afec7fc9af483898ecaf3 F test/multiplex.test dc0d67b66f84b484a83cb8bbdf3f0a7f49562ccd F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101 F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 -F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 -F test/nockpt.test 9a436a7213ba5ef7a32304998d386d3ea3f76c9d +F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1 +F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e +F test/normalize.test 1dedf653ca33b0b55fd0c7967d2861a51f1801a7aa899a02d4c0d7adfcd5acdc F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 -F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62 +F test/notnull.test b6999231221df3534827e45e2005dd7a815fdd5f2c2e1afb9be21ead410816f8 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 -F test/orderby1.test 4d22a7c75f6a83fc1f188cc7bb5192285fdf2552 +F test/optfuzz-db01.c a0c256905c8ac79f9a5de2f374a3d9f757bef0dca2a238dc7c10cc8a38031834 +F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041 +F test/optfuzz.c 50e330304eb1992e15ddd11f3daaad9bcc0d9aaad09cb2bcc77f9515df2e88b1 +F test/orderby1.test e4501f54721f804ca56922e253403ac6775f88e9f07569994ce99212b3ca5b10 F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04 F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99 F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4 -F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb +F test/orderby5.test 5f4d6cb93cc2f6d3f4228354310a2ce1fbd95d5bbffcba8c6482eeb62a466407 F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 -F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f -F test/ossfuzz.c 7f5cc87a0280a5854c1bfa7d5c4d07d34731f08ec34dc9c916aa35ed292b1468 -F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622 +F test/oserror.test e7b3416be4b9d5dd2fe0b42dd394daaddbb6c83eeec1f0e47b120b53e0ad3ace +F test/ossfuzz.c c4c4547e2c92ac52f10038b073a03248251a23c1c559728f63a18aeca0e79f03 +F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f -F test/pager1.test 8149b2a8986fee667ab6a8171ab310be19e77ae215bebad0e90c857b0df1935c +F test/pager1.test a32ce299ed01ffb06e84a3af467ae1f3389786b316f40c4359f442c79144736b F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 -F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f +F test/pager3.test 4e9a83d6ca0838d7c602c9eb93d1357562d9059c1e02ffb138a8271020838370 F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e -F test/pagerfault.test 263c5442c06caf0b9b9e3fe42acdeb11f254dcebe533f69f401aaef9111eaf20 +F test/pagerfault.test 63c5da625562c66345ab4528790327ca63db2f6f9cbae2aba8cb7c51de3d1628 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0 @@ -1089,14 +1171,16 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 3b94f8fd431d39fac4952eb5dc38e1bb2b4518e1ac967d66f5abc815c104aeb6 -F test/pragma.test f274259d6393b6681eb433beb8dd39a26ec06a4431052a4880b43b84912a3f58 +F test/permutations.test 8749e292c8f7e98072049543da8c0fe60e1625f0a9f49068623060984c176bbf +F test/pg_common.tcl 301ac19c1a52fd55166d26db929b3b89165c634d52b5f8ad76ea8cb06960db30 +F test/pragma.test 7c8cfc328a1717a95663cf8edb06c52ddfeaf97bb0aee69ae7457132e8d39e7d F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed -F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264 +F test/pragma4.test 3046501bee2f652dc2a4f9c87781e2741361d6864439c8381aba6c3b774b335c +F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 -F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc -F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad +F test/printf.test a3e559bc9d922e7fe44e9d05c6965fee34fe3bc28300a4248c6a063425246ffd +F test/printf2.test 30b5dd0b4b992dc5626496846ecce17ff592cacbcb11c3e589f3ac4d7e129dae F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/pushdown.test 5e72c51c5e33253ed639ccee1e01ce62d62b6eee5ca893cd82334e4ee7b1d7fc @@ -1113,19 +1197,20 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 7bb585433ce7fb2a2c255ae4b5e24f1bc27fe177ec1120f886cc4852f48f5ee9 x +F test/releasetest.tcl c5b474f9880073fc3b69729ee05d5284653a9ee101af572204917d9dcb1d9015 x +F test/resetdb.test 684a6ffde5a5141bba79f3101981cc38dcfc3403f61e643b7b3aa68bef0b8408 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/reuse1.test 04ae701b4000113fedc472719e4cf4bb1d34d22dcaf8d3e643d41d1256a9590d -F test/rollback.test f580934279800d480a19176c6b44909df31ce7ad45267ea475a541daa522f3d3 -F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 +F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa +F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 44f3492f415cc9f374e8388a5eb61503eaca5230 +F test/rowvalue.test ef851a80f7e6de93b51caca9e4b6b7d2dcd540bbcca7d51860e80435b8b4c0de F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 -F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea +F test/rowvalue4.test 2b20468da3775aba971caf3158e9696a4d99c69a7623fb495f332a596daebbee F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 @@ -1141,33 +1226,36 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 -F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 +F test/scanstatus.test d14842d0a2757ee059bcffa365746453d60952ba1077980c9a348a9fefbd232a F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 F test/schema4.test 3b26c9fa916abb6dadf894137adcf41b7796f7b9 F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e -F test/schema6.test 5b21bbdd405bc93b3e6af5e6ece64d230e35f65cc4035e5c2b89fc8a090d7270 -F test/securedel.test 5f997cb6bd38727b81e0985f53ec386c99db6441b2b9e6357240649d29017239 +F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce1f9b +F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e +F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 -F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686 +F test/select1.test 2e760bab8f3658b3b97debcf52860d0d2e20aa6cbe8b40e678ddb99871a15491 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328 -F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 +F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select7.test f659f231489349e8c5734e610803d7654207318f F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 -F test/selectA.test 101e722370ac6e84978c2958b8931c78b10a1709 +F test/selectA.test b8a590f6493cad5b0bb4dfe1709bf7dcda0b6c40bb4caf32d1e36a89eebc8fc5 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectC.test e25243f8ca503e06f252eb0218976d07cfeceac3 -F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 +F test/selectD.test fc20452847a01775710090383cfb4423275d2f745fed61f34fbf37573ac0d214 F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 -F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982 -F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 +F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae8840 +F test/server1.test c2b00864514a68a0e6fd518659dc95d0050307a357a08969872bef027d785dc4 F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be +F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb +F test/sessionfuzz.c b0fcdcf757451957e17396a3af5171f1fdf9b2babc81da9fa35675df46c4729a F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746 F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38 @@ -1176,36 +1264,41 @@ F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test a81e99f83e6c51b02ac99c96fb3a2a7b5978c956 F test/shared8.test 00a07bf5e1337ecf72e94542bdefdc330d7a2538 F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 -F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 +F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69e281 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test f78ea0e2637ae9f497cb41206f6346f983052ffc7a359e664aaf6847fc704ea7 +F test/shell1.test d2bf5daeb6f449f0169c9ef3094db17a16a02199c5dcf1a635a3e79b07eb0edd F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b -F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 +F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 23939a4c51f0421330ea61dbd3c74f9c215f5f8d3d1a94846da6ffc777a35458 -F test/shell6.test ab1592ebe881371f651f18ee6a0df21cbfb5310f88cb832ab642d4038f679772 +F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f +F test/shell8.test 96be02ea0c21f05b24c1883d7b711a1fa8525a68ab7b636aacf6057876941013 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 -F test/skipscan1.test 8ab5d2c7c5cd3fe7f172d366e6e74e887cb33cb4 -F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a +F test/skipscan1.test 3ea1cccca8f1b0e1cf3e73a63b43dd796f34d4aaee815e641f0d2ebb3fa448d4 +F test/skipscan2.test ef143c6e4a5ba4f19c1d1e3f517811f7942bdf2142736cc568feb34e0b5fb763 F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 -F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f -F test/snapshot2.test 867652ed4a13282dce218723535fad1c7b44c3c4 -F test/snapshot_fault.test 52c5e97ebd218846a8ae2da4d147d3e77d71f963 -F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f +F test/skipscan6.test 0b4cd1b4ac9f84d91454df513c99a4932fa07e8f27b8049bea605068b3e34ac7 +F test/snapshot.test a504f2e7009f512ef66c719f0ea1c55a556bdaf1e1312c80a04d46fc1a3e9632 +F test/snapshot2.test 4fc84a0121e882d6980333bf14dfc1143dfb94f5afbb909c084977a945b45beb +F test/snapshot3.test d6ec952e437e5c06a293d0f5ec1be1b45771d46d93bccfb3818ca2617dcb11e7 +F test/snapshot4.test 0f7e6bd6f1370d112ee820c541d0dd0e7b8ab4ea77429e65106d81c9ad2185a6 +F test/snapshot_fault.test 508ae6f211d4991e9ff3b5080aeb0a179bf6755138aabeac4bca8083044d895a +F test/snapshot_up.test 93fec2d847ec12e3bae0f6486da2abc965a606e099e4e870454045f5f56f71ba +F test/soak.test 18944cf21b94a7fe0df02016a6ee1e9632bc4e8d095a0cb49d95e15d5cca2d5c F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0 F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5 F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c -F test/sort5.test 30cc17768e0c06ecb048e08efec59c11811fd186 +F test/sort5.test 6b43ae0e2169b5ceed441844492e55ba7f1ae0790528395ddf7888ab3094525d +F test/sorterref.test a13ed207a0eea3c7898f308f979bfb518f68c598ec737d2c494dfd3deaa83506 F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb @@ -1214,47 +1307,49 @@ F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa -F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 7b1ab42b097b484c18d99e1d1c71a6a0c9c87a7a -F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db +F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c +F test/speedtest1.c cc7e6b4a7c9f3e3d1a497ae3f75236a832a2ce0f6a9b017f95d996c821605bfb +F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 +F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/stat.test f8f1279ffffabe6df825723af18cc6e0ae70a893 F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 -F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f -F test/stmtvtab1.test acc3c40f484f2c4922e270724383d715abb9d69676da907a9c64f31c54f2ef9f +F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec75 +F test/stmtvtab1.test 6873dfb24f8e79cbb5b799b95c2e4349060eb7a3b811982749a84b359468e2d5 F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49 F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f -F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f +F test/subquery2.test 8250dfd6a773b04c7a5c37ac63276f62b329157ce171244d0cbe1acc365e3303 F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 -F test/swarmvtab.test 05c4ca7b6ab0cc6f4c335a510347f99d741fa71366004699cf7dfa3cff4e2d17 -F test/swarmvtab2.test 038ef9bcad6fd2fb9e395196080cf23e223ddb1219015049a61540c161bc577d -F test/swarmvtabfault.test 73563eefe3073c6fb3bb14475fb4ef5d4f2e3a67a02947ee0ca08980ea3dd7fe -F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 -F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 -F test/sync2.test 6be8ed007fa063b147773c1982b5bdba97a32badc536bdc6077eff5cf8710ece +F test/swarmvtab.test 9a3fd5ab3e9b3c976ad1b3d7646aab725114f2ac26b59395d0778b33bab6cdaf +F test/swarmvtab2.test c948cb2fdfc5b01d85e8f6d6504854202dc1a0782ab2a0ed61538f27cbd0aa5c +F test/swarmvtab3.test 6cb664669630fcec4102a09333e52068734858fd2761eee3b0465c14cdbcee29 +F test/swarmvtabfault.test 00aec54665909490f5c383f3cae3b5d18bd97c12490b429ff8752a3027acfa42 +F test/symlink.test 0d816670325536b8973ec08d32b45136baddb80bd45fd178e0ce7a9e8153f3e7 +F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d4333092 +F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test c47171c36b3d411df2bd49719dcaa5d034f8d277477fd41d253940723b969a51 +F test/tabfunc01.test 5ddfdcda81f362d54cf301a65678edea2a02a570760a4c88051fc2730aafcd81 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f -F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 +F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test d1fc287635da11f60b9243022b2332b667fbb9bdfb3d22b884a2e7d506afffd1 -F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 -F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507 +F test/tclsqlite.test 049da602775bebfadfa2fae0710e1099a38ef2fc9f76c7546be3ba8fdbb02263 +F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 +F test/tempdb2.test 4749545409c6d7438b435c3f05cdd139cf4145a954a6908d19e3443ffd8724b3 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e +F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl eb7ec55fe074a909423c1de701f7c545417b8aa96787b8c3e7a79203f2cebec8 -F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 +F test/tester.tcl fa5656391e3b477508abe12b3b81f019b2e71397399ab38a2f32d8d7f3bf8e56 +F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f @@ -1268,13 +1363,13 @@ F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c -F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 +F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2 F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58 F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d -F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e +F test/tkt-385a5b56b9.test 5204a7cba0e28c99df0acbf95af5e1af4d32965a7a14de6eccebf949607618b1 F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678 F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3a77c9714e.test b08bca26de1140bdf004a37716582a43d7bd8be8 @@ -1289,8 +1384,8 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336 F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf -F test/tkt-78e04e52ea.test 1b2e6bf4f1d9887b216b6da774e5f25915ec8118 -F test/tkt-7a31705a7e6.test e75a2bba4eec801b92c8040eb22096ac6d35e844 +F test/tkt-78e04e52ea.test 1b5be1bac961833a9fd70fe50738cb4064822c61f82c54f7d488435ec806ea62 +F test/tkt-7a31705a7e6.test 9e9c057b6a9497c8f7ba7b16871029414ccf6550e7345d9085d6d71c9a56bb6f F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18 F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8 F test/tkt-80e031a00f.test 9ee36348b761bf7c14261e002b75a4c0d5a04d4c @@ -1303,15 +1398,16 @@ F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667 F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6 F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8 F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4 -F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9 +F test/tkt-a8a0d2996a.test 76662ff0622c90e7ce7bbcb4d9e1129acddf877d17c3489f2da7f17ddfaad1f4 F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3 -F test/tkt-b75a9ca6b0.test 97cc2d5eeaf82799eb42138c0a1ff64370238ce4 +F test/tkt-b75a9ca6b0.test 1bc0381538fd21f96a10dbabc10ffc51b5b2e5f412d34bae571273ca784003d7 F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447 +F test/tkt-c694113d5.test 82c461924ada5c14866c47e85535b0b0923ba16a2e907e370061a5ca77f65d77 F test/tkt-cbd054fa6b.test 06ccd57af3c0c7895d0f7dc844f13c51f8258885 F test/tkt-d11f09d36e.test d999b548fef885d1d1afa49a0e8544ecf436869d F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 @@ -1367,13 +1463,13 @@ F test/tkt3121.test 536df66a02838c26a12fe98639354ca1290ca68b F test/tkt3201.test f1500ccecc0d578dc4cde7d3242008297c4d59b3 F test/tkt3292.test 962465a0984a3b8c757efe59c2c59144871ee1dd F test/tkt3298.test 20fd8773b825cb602e033aa04f8602e1ebdcd93c -F test/tkt3334.test ea13a53cb176e90571a76c86605b14a09efe366d +F test/tkt3334.test 9756631e3c4aa3c416362c279e3c0953a83b7ca8274cb81a13264bb56296d8b0 F test/tkt3346.test 6f67c3ed7db94dfc5df4f5f0b63809a1f611e01a F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812 -F test/tkt3442.test 53840ec5325bb94544792aad4c20476f81dc26b1 -F test/tkt3457.test 44e980fe5334753dcc27b94fa4deabc485a92f74 +F test/tkt3442.test a1fc47c669e651d16494de3ff349bcb53281456f2ca02c8bc14220b6044bbfe8 +F test/tkt3457.test 5651e2cbb94645b677ec663160b9e192b87b7d365aecdfb24e19f749575a6fc2 F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19 F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218 F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d @@ -1408,30 +1504,30 @@ F test/tkt3992.test f3e7d548ac26f763b47bc0f750da3d03c81071da F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd F test/tkt4018.test 18dbc6617f7a4b90e938d1bd6d26ad18daafaf08 F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 -F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 -F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 +F test/tpch01.test 7c4eb8cdd79c568f46d344b3e789c9fdb8a766d112871352704861f3fca32a2a +F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test 56ab944fddacf628b118cc298503fc45c2e50ab0 +F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/transitive1.test 293300f46916569f08875cdb2fe2134be2c27677 -F test/trigger1.test ea9624cc1dae05645469df6119fa815f9e6f1e8c +F test/trigger1.test 17e4b43e656c4b354df2357634a6ba887990f510c43629f4feca30e3338d2a61 F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9 -F test/trigger7.test 799c9d2561facef70340cc9e0dee98aee9b5bdfe +F test/trigger7.test 93cfa9b48ab9104b2b3d87bc544ac8021405643e36f23ee84635fbfaf9b8fef5 F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4 F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41 -F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332 +F test/triggerA.test 837be862d8721f903dba3f3ceff05b32e0bee5214cf6ea3da5fadf12d3650e9d F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 -F test/triggerE.test 15fa63f1097db1f83dd62d121616006978063d1f +F test/triggerE.test d9e9b364dfd527c84ac0de53045406325487feecb32888d482eca64421a50d99 F test/triggerF.test 6a8c22bd058cf467f0c7d112afe87f7a8c579c0c4681b914b8f19020f48528a4 -F test/triggerG.test 175cafdc6399d85231a09e82e051b0e45a2fd1f23dd08ae715bc359716149ab6 +F test/triggerG.test d5caeef6144ede2426dd13211fd72248241ff2ebc68e12a4c0bf30f5faa21499 F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1445,9 +1541,14 @@ F test/unionvtabfault.test 26b6854d5aef9005cd630513025690bff1b7378ae9c97b81e2a3c F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 -F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 -F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 -F test/update2.test fffc92e72ae568fe048588762e650cd8ccbd8c8b6e4fe9099231766bfe4b51de +F test/unordered.test ffeea7747d5ba962a8009a20b7e53d68cbae05b063604c68702c5998eb50c981 +F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60 +F test/update2.test 5e67667e1c54017d964e626db765cf8bedcf87483c184f4c575bdb8c1dd2313e +F test/upsert1.test 994bde41800bb77dbe32fcd2e1f6c4b49cc9f2c6cd345731c774dff02b51c110 +F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 +F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c +F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 +F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 @@ -1455,14 +1556,14 @@ F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d -F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuum5.test c87234e8ca4107f349da4edbeda3e4ea5adc93f3 +F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7c010 +F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 -F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 +F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 -F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab +F test/view.test 71e1bf4c0e2e0d37c84d7db5b33cd47eb4a7662c19d93ede4112b350b186f61f F test/vtab1.test 8f91b9538d1404c3932293a588c4344218a0c94792d4289bb55e41020e7b3fff -F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad +F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391 @@ -1474,15 +1575,16 @@ F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796 F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 -F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe +F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b45f F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test 26d54e8b5407f797638b787a55f9c88323850a58dd142de02d06b9a1159bd283 +F test/vtabH.test 3cf9aa1c1c4381b3b3ac33f933376f06fbb99d2294a83c79b7562d3ed87be450 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f +F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783 -F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 +F test/vtab_err.test 1c476cac24c9c730f83cd7c8bf66482a30151be08d36a2283f87fc38a2dacbb1 F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477 -F test/wal2.test 56b0bc95b8693a0be294f8d210c49025dd094bd7 +F test/wal2.test 155b9efa999bdb38ce1cd729b9a4fcdbffd6b88be27f039bad1d2929d287d918 F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 @@ -1500,62 +1602,82 @@ F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af F test/walcrash4.test e7b6e7639a950a0cca8e210e248c8dad4d63bf20 -F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b +F test/walfault.test 09b8ad7e52d2f54bce50e31aa7ea51412bb9f70ac13c74e669ddcd8b48b0d98d F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 -F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c +F test/walmode.test cd6e7cff618eaaa5910ce57c3657aa50110397f86213886a2400afb9bfec7b7b F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03 F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 -F test/walprotocol.test 0b92feb132ccebd855494d917d3f6c2d717ace20 -F test/walro.test 4ab7ac01b77c2f894235c699d59e3e3c7f15a160 +F test/walprotocol.test a112aba0b79e3adeaa485fed09484b32c654e97df58e454aa8489ac2cd57bf84 +F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db868eebc131 +F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20 +F test/walro2.test 0e79dd15cbdb4f482c01ea248373669c732414a726b357d04846a816afafb768 +F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f -F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e -F test/where.test f0c325563acde44f2c4ea6ba348e9e29f7121757 +F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 +F test/where.test 480cfc1758ac9df3f70c6a2541ff586f6a4833354d5ecb548f643e30e31fddc8 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 -F test/where3.test 54cdeb02157acc979de41530b804ae7b09552bf1 +F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b -F test/where7.test f520bcec2c3d12dc4615623b06b2aec7c2d67e94 -F test/where8.test 98eedca0d375fb400b8377269c4b4686582dfb45 -F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2 +F test/where7.test e579da972eb3372edc9de850efc221848c763f9e4feafc8426d84a4453b92b23 +F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f +F test/where9.test ad2ddb339d10d324763c3da60502b8631f15a2397b869192fbd4e82f40e167d3 F test/whereA.test 6c6a420ca7d313242f9b1bd471dc80e4d0f8323700ba9c78df0bb843d4daa3b4 F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002 F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f -F test/whereF.test 97a86ecdfa4c21684fdff501dbd2cb7397689be8676d0dbad1f5a0892c6b56a3 -F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501 +F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89 +F test/whereG.test 0158783235a6dd82fc0e37652b8522b186b9510594ac0a4bff0c4101b4396a52 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 -F test/whereI.test eab5b226bbc344ac70d7dc09b963a064860ae6d7 -F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 +F test/whereI.test b7769ee8dbefd987fb266715fee887f05f9ff180016b06fca7fa402df739193b +F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b +F test/whereL.test 84de61afe4b8e5a3ff7d741c990d85cb44b3ce798cd8412d5603930f3f75014f F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 -F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 +F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 +F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0 +F test/wherelimit2.test be78ba3aa1831c6358fd7d5b9809bfd520f0c2a7d63a295e8f182e140ff137c3 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c -F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c +F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc -F test/with1.test 732e3ef398dcecb609839cd5ef0cb63beb2a9eff31420f3b745fc55b9e85b61e -F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87 -F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6 +F test/window1.test 474bef1a6ac291755e51d1f9458dc11117c1870ac5e08b4d3938649b215f8334 +F test/window2.tcl 9bfa842d8a62b0d36dc8c1b5972206393c43847433c6d75940b87fec93ce3143 +F test/window2.test 8e6d2a1b9f54dfebee1cde961c8590cd87b4db45c50f44947a211e1b63c2a05e +F test/window3.tcl 577a3b1ff913208e5248c04dab9df17fd760ce159a752789e26d0cb4a5f91823 +F test/window3.test e274b7f8952ca4ed25996e0e45c047192b066e0aaff2a822d4293c8c4f1d8d98 +F test/window4.tcl 511425f6b0abf9b953df54cc9c7295cc7c25d78f4ed6f7a74b094eec0120eccb +F test/window4.test c5d6bf3403e4ade2f19df2afe4c16f29fb817c392c6c1c8017edb7165c191a62 +F test/window5.test 8187f46597c90b73e8f96659e893353cbda337479cc582f7a488eab351ba08d3 +F test/window6.test 5eae4ae7a590ccf1e605880969ca0bad3955616ac91cad3031baea38748badb3 +F test/windowfault.test 23abad97b72c6f609002255ddd41ef5c8922408f918f9b98ad6005ab316e482f +F test/with1.test 2465d98ffce80d00553ac7135697c18b0369275b6ecc750daa2af320b8c812ca +F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab +F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d +F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 -F test/without_rowid1.test 06b7215130882d6a072233820dd364c874c4fd69221e8fc756ec471009192874 +F test/without_rowid1.test 533add9100255e4cc430d371b3ecfb79f11f956b86c3a1b9d34413bf8e482d8f F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 -F test/without_rowid3.test 2724c787a51a5dce09d078453a758117b4b728f1 +F test/without_rowid3.test e1bb85362d9b7b63ea2b93c433bb2923fff8badb98e463474365531c1cd5f880 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e -F test/wordcount.c 06efb84b7c48a4973c2c24ea06c93d00bce24389 +F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912adec66 F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa -F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e +F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc +F test/zipfile.test a61f6ba6dbaaf4983849df84a31df140c7ddd1362e2fa9ecd3cdf5cd123b7f18 +F test/zipfile2.test 8a18965530258140ce301b2c2f4245bc505ffead2e17a97fa34c7ace379ea5e0 +F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 -F tool/addopcodes.tcl 7181c041d495e3f26acc36d15c86923ed722285f9015f017f41a3efdb9a0dab4 +F tool/addopcodes.tcl 0288d5b26b9b35f4cb5affb76eec63f1dfce117bbc2020066708069ef60b86ff F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x @@ -1569,25 +1691,27 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c e6056373044d55296d21f81467dba7632bbb81dc49af072b3f0e76338771497e -F tool/lempar.c 10579a61dc2290182725e7abdefe311dd8b521a8f7f0aabbfc571e9012a09eaf +F tool/lemon.c 60d1e1eb0f7ebae709f68f1472d77fbf291c5345cd98ff417219da7e74fd09e9 +F tool/lempar.c 6020ce61dd7a536a3866952eb1e616c7e8b14b8f623368ed5a98f0639cedf048 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 -F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 +F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e +F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c 2e852ac0dfdc5af18886dc1ce7e9676d11714ae3df0a282dc7d90b3a0fe2033c -F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66eefaa4 +F tool/mkkeywordhash.c 1f7f2ac1d9f262c08b67faaca47e6a68262ff39113fa4b27d1db2843b4c33e73 +F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6a13ea F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c -F tool/mkopcodeh.tcl 4ee2a30ccbd900dc4d5cdb61bdab87cd2166cd2affcc78c9cc0b8d22a65b2eee -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd -F tool/mkshellc.tcl 69c38ecd7b74b2b0799a35ce20e1e3998e504d8c99c100ca4b98ae9d8f6279bc +F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 +F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa +F tool/mkpragmatab.tcl fc895d5a40e725b19b866b058b3994bfc45db3e7fef40db9e6c6fd921bf8a337 +F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5 +F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 -F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb -F tool/mksqlite3c.tcl a4b36eaa002ed00a0ab2c93d999a14f1acae98ff09a85382e5abc05a91edb82b -F tool/mksqlite3h.tcl 51bd5e7e840a920388a5966c9f2ccc618f434c57bd68c1bab4085b2553e1e237 +F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f +F tool/mksqlite3c.tcl 5fed3d75069d8f66f202d3b5200b0cea4aa7108481acd06732a06fdd42eb83a2 +F tool/mksqlite3h.tcl 080873e3856eceb9d289a08a00c4b30f875ea3feadcbece796bd509b1532792c F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1601,27 +1725,30 @@ F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 F tool/showdb.c e6bc9dba233bf1b57ca0a525a2bba762db4e223de84990739db3f09c46151b1e F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 +F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809 F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c2a1 F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe -F tool/spaceanal.tcl f40dc82b4d5e39d040a02a3ec38268e324068815e4292a15ffa30ee93208bbfd -F tool/speed-check.sh fd24151fd66465f01886c3f75faf8fa46d19f068c69d16514ca73887adcdafe4 +F tool/spaceanal.tcl 4bfd19aad7eb3ce0372ef0255f58035e0bba4ff5e9acfd763a10c6fb365c8dec +F tool/speed-check.sh 27c7fe178d5b2f7c90a04a127907acda0bfe637fa85b13c43e03e5ed39b008b6 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd -F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c 30879bbc8de686df4624e86adce2d8981f500904c1cfb55b5d1eea2ffd9341eb +F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c +F tool/sqldiff.c 579d7e4e42c30a963781654c87d2868823120b55d59e16ca77b0edbab0218713 +F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968 +F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 +F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148 -F tool/tostr.tcl 96022f35ada2194f6f8ccf6fd95809e90ed277c4 F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f -F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 +F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 8a4acea31e0f9c562949a2d767329533c0930d699ea19c6704c0ca0aa9154068 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85 @@ -1645,10 +1772,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 94434a252f0f2b57f325fd8fb82534f20cc1340ff13076cd88deeb47740ef6a2 -R ed2f8a5054bbb201ae29fcc7757dba48 -T *branch * reuse-schema -T *sym-reuse-schema * -T -sym-trunk * +P a625698048c05375f12ea8875892fdbf3518291f10917fe68dd2294280cd3b42 690dd18a5768c5a8cdfa92d5b01901c1a7b1fb6ebb90399f56a3112e41609f92 +R fe6beb8363bb52b29ad9017127c5a25d U dan -Z 6d545754cdf84dd62577616fb01f7f9c +Z 3140f4ddf8569ce4edd6a8cc2929ebcb diff --git a/manifest.uuid b/manifest.uuid index fe6f444d26..da2645ce6e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a625698048c05375f12ea8875892fdbf3518291f10917fe68dd2294280cd3b42 \ No newline at end of file +2ac72114a1f5344b42472b941c60f460c28c981a22ea40909b30f7bf4eb4b11b \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index b1aedd3a75..71477a9fb2 100644 --- a/src/alter.c +++ b/src/alter.c @@ -20,352 +20,6 @@ */ #ifndef SQLITE_OMIT_ALTERTABLE - -/* -** This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TABLE or -** CREATE INDEX command. The second is a table name. The table name in -** the CREATE TABLE or CREATE INDEX statement is replaced with the third -** argument and the result returned. Examples: -** -** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') -** -> 'CREATE TABLE def(a, b, c)' -** -** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') -** -> 'CREATE INDEX i ON def(a, b, c)' -*/ -static void renameTableFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - - sqlite3 *db = sqlite3_context_db_handle(context); - - UNUSED_PARAMETER(NotUsed); - - /* The principle used to locate the table name in the CREATE TABLE - ** statement is that the table name is the first non-space token that - ** is immediately followed by a TK_LP or TK_USING token. - */ - if( zSql ){ - do { - if( !*zCsr ){ - /* Ran out of input before finding an opening bracket. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = (char*)zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and its length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - } while( token==TK_SPACE ); - assert( len>0 ); - } while( token!=TK_LP && token!=TK_USING ); - - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), - zSql, zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); - } -} - -/* -** This C function implements an SQL user function that is used by SQL code -** generated by the ALTER TABLE ... RENAME command to modify the definition -** of any foreign key constraints that use the table being renamed as the -** parent table. It is passed three arguments: -** -** 1) The complete text of the CREATE TABLE statement being modified, -** 2) The old name of the table being renamed, and -** 3) The new name of the table being renamed. -** -** It returns the new CREATE TABLE statement. For example: -** -** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3') -** -> 'CREATE TABLE t1(a REFERENCES t3)' -*/ -#ifndef SQLITE_OMIT_FOREIGN_KEY -static void renameParentFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_context_db_handle(context); - char *zOutput = 0; - char *zResult; - unsigned char const *zInput = sqlite3_value_text(argv[0]); - unsigned char const *zOld = sqlite3_value_text(argv[1]); - unsigned char const *zNew = sqlite3_value_text(argv[2]); - - unsigned const char *z; /* Pointer to token */ - int n; /* Length of token z */ - int token; /* Type of token */ - - UNUSED_PARAMETER(NotUsed); - if( zInput==0 || zOld==0 ) return; - for(z=zInput; *z; z=z+n){ - n = sqlite3GetToken(z, &token); - if( token==TK_REFERENCES ){ - char *zParent; - do { - z += n; - n = sqlite3GetToken(z, &token); - }while( token==TK_SPACE ); - - if( token==TK_ILLEGAL ) break; - zParent = sqlite3DbStrNDup(db, (const char *)z, n); - if( zParent==0 ) break; - sqlite3Dequote(zParent); - if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ - char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", - (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew - ); - sqlite3DbFree(db, zOutput); - zOutput = zOut; - zInput = &z[n]; - } - sqlite3DbFree(db, zParent); - } - } - - zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), - sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); - sqlite3DbFree(db, zOutput); -} -#endif - -#ifndef SQLITE_OMIT_TRIGGER -/* This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER -** statement. The second is a table name. The table name in the CREATE -** TRIGGER statement is replaced with the third argument and the result -** returned. This is analagous to renameTableFunc() above, except for CREATE -** TRIGGER, not CREATE INDEX and CREATE TABLE. -*/ -static void renameTriggerFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - int dist = 3; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - sqlite3 *db = sqlite3_context_db_handle(context); - - UNUSED_PARAMETER(NotUsed); - - /* The principle used to locate the table name in the CREATE TRIGGER - ** statement is that the table name is the first token that is immediately - ** preceded by either TK_ON or TK_DOT and immediately followed by one - ** of TK_WHEN, TK_BEGIN or TK_FOR. - */ - if( zSql ){ - do { - - if( !*zCsr ){ - /* Ran out of input before finding the table name. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = (char*)zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and its length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - }while( token==TK_SPACE ); - assert( len>0 ); - - /* Variable 'dist' stores the number of tokens read since the most - ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN - ** token is read and 'dist' equals 2, the condition stated above - ** to be met. - ** - ** Note that ON cannot be a database, table or column name, so - ** there is no need to worry about syntax like - ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. - */ - dist++; - if( token==TK_DOT || token==TK_ON ){ - dist = 0; - } - } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); - - /* Variable tname now contains the token that is the old table-name - ** in the CREATE TRIGGER statement. - */ - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), - zSql, zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); - } -} -#endif /* !SQLITE_OMIT_TRIGGER */ - -/* -** Register built-in functions used to help implement ALTER TABLE -*/ -void sqlite3AlterFunctions(void){ - static FuncDef aAlterTableFuncs[] = { - FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), -#ifndef SQLITE_OMIT_TRIGGER - FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), -#endif -#ifndef SQLITE_OMIT_FOREIGN_KEY - FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), -#endif - }; - sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); -} - -/* -** This function is used to create the text of expressions of the form: -** -** name= OR name= OR ... -** -** If argument zWhere is NULL, then a pointer string containing the text -** "name=" is returned, where is the quoted version -** of the string passed as argument zConstant. The returned buffer is -** allocated using sqlite3DbMalloc(). It is the responsibility of the -** caller to ensure that it is eventually freed. -** -** If argument zWhere is not NULL, then the string returned is -** " OR name=", where is the contents of zWhere. -** In this case zWhere is passed to sqlite3DbFree() before returning. -** -*/ -static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ - char *zNew; - if( !zWhere ){ - zNew = sqlite3MPrintf(db, "name=%Q", zConstant); - }else{ - zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant); - sqlite3DbFree(db, zWhere); - } - return zNew; -} - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) -/* -** Generate the text of a WHERE expression which can be used to select all -** tables that have foreign key constraints that refer to table pTab (i.e. -** constraints for which pTab is the parent table) from the sqlite_master -** table. -*/ -static char *whereForeignKeys(Parse *pParse, Table *pTab){ - FKey *p; - char *zWhere = 0; - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName); - } - return zWhere; -} -#endif - -/* -** Generate the text of a WHERE expression which can be used to select all -** temporary triggers on table pTab from the sqlite_temp_master table. If -** table pTab has no temporary triggers, or is itself stored in the -** temporary database, NULL is returned. -*/ -static char *whereTempTriggers(Parse *pParse, Table *pTab){ - Trigger *pTrig; - char *zWhere = 0; - const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */ - - /* If the table is not located in the temp-db (in which case NULL is - ** returned, loop through the tables list of triggers. For each trigger - ** that is not part of the temp-db schema, add a clause to the WHERE - ** expression being built up in zWhere. - */ - if( pTab->pSchema!=pTempSchema ){ - sqlite3 *db = pParse->db; - for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ - if( pTrig->pSchema==pTempSchema ){ - zWhere = whereOrName(db, zWhere, pTrig->zName); - } - } - } - if( zWhere ){ - char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere); - sqlite3DbFree(pParse->db, zWhere); - zWhere = zNew; - } - return zWhere; -} - -/* -** Generate code to drop and reload the internal representation of table -** pTab from the database, including triggers and temporary triggers. -** Argument zName is the name of the table in the database schema at -** the time the generated code is executed. This can be different from -** pTab->zName if this function is being called to code part of an -** "ALTER TABLE RENAME TO" statement. -*/ -static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ - Vdbe *v; - char *zWhere; - int iDb; /* Index of database containing pTab */ -#ifndef SQLITE_OMIT_TRIGGER - Trigger *pTrig; -#endif - - v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return; - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 ); - -#ifndef SQLITE_OMIT_TRIGGER - /* Drop any table triggers from the internal schema. */ - for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ - int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); - assert( iTrigDb==iDb || iTrigDb==1 ); - sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); - } -#endif - - /* Drop the table and index from the internal schema. */ - sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); - - /* Reload the table, index and permanent trigger schemas. */ - zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); - if( !zWhere ) return; - sqlite3VdbeAddParseSchemaOp(pParse, iDb, zWhere); - -#ifndef SQLITE_OMIT_TRIGGER - /* Now, if the table is not stored in the temp database, reload any temp - ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3VdbeAddParseSchemaOp(pParse, 1, zWhere); - } -#endif -} - /* ** Parameter zName is the name of a table that is about to be altered ** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). @@ -382,6 +36,49 @@ static int isSystemTable(Parse *pParse, const char *zName){ return 0; } +/* +** Generate code to verify that the schemas of database zDb and, if +** bTemp is not true, database "temp", can still be parsed. This is +** called at the end of the generation of an ALTER TABLE ... RENAME ... +** statement to ensure that the operation has not rendered any schema +** objects unusable. +*/ +static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM \"%w\".%s " + "WHERE name NOT LIKE 'sqlite_%%'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", + zDb, MASTER_NAME, + zDb, bTemp + ); + + if( bTemp==0 ){ + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM temp.%s " + "WHERE name NOT LIKE 'sqlite_%%'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", + MASTER_NAME, zDb + ); + } +} + +/* +** Generate code to reload the schema for database iDb. And, if iDb!=1, for +** the temp database as well. +*/ +static void renameReloadSchema(Parse *pParse, int iDb){ + Vdbe *v = pParse->pVdbe; + if( v ){ + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(pParse, iDb, 0); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse, 1, 0); + } +} + /* ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" ** command. @@ -399,9 +96,6 @@ void sqlite3AlterRenameTable( int nTabName; /* Number of UTF-8 characters in zTabName */ const char *zTabName; /* Original name of the table */ Vdbe *v; -#ifndef SQLITE_OMIT_TRIGGER - char *zWhere = 0; /* Where clause to locate temp triggers */ -#endif VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ u32 savedDbFlags; /* Saved value of db->mDbFlags */ @@ -474,8 +168,63 @@ void sqlite3AlterRenameTable( if( v==0 ){ goto exit_rename_table; } - sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); - sqlite3ChangeCookie(pParse, iDb); + + /* figure out how many UTF-8 characters are in zName */ + zTabName = pTab->zName; + nTabName = sqlite3Utf8CharLen(zTabName, -1); + + /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in + ** the schema to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " + "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" + "AND name NOT LIKE 'sqlite_%%'" + , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName + ); + + /* Update the tbl_name and name columns of the sqlite_master table + ** as required. */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET " + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " + "ELSE name END " + "WHERE tbl_name=%Q COLLATE nocase AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, MASTER_NAME, + zName, zName, zName, + nTabName, zTabName + ); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If the sqlite_sequence table exists in this database, then update + ** it with the new table name. + */ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", + zDb, zName, pTab->zName); + } +#endif + + /* If the table being renamed is not itself part of the temp database, + ** edit view and trigger definitions within the temp database + ** as required. */ + if( iDb!=1 ){ + sqlite3NestedParse(pParse, + "UPDATE sqlite_temp_master SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " + "tbl_name = " + "CASE WHEN tbl_name=%Q COLLATE nocase AND " + " sqlite_rename_test(%Q, sql, type, name, 1) " + "THEN %Q ELSE tbl_name END " + "WHERE type IN ('view', 'trigger')" + , zDb, zTabName, zName, zTabName, zDb, zName); + } /* If this is a virtual table, invoke the xRename() function if ** one is defined. The xRename() callback will modify the names @@ -491,90 +240,8 @@ void sqlite3AlterRenameTable( } #endif - /* figure out how many UTF-8 characters are in zName */ - zTabName = pTab->zName; - nTabName = sqlite3Utf8CharLen(zTabName, -1); - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - if( db->flags&SQLITE_ForeignKeys ){ - /* If foreign-key support is enabled, rewrite the CREATE TABLE - ** statements corresponding to all child tables of foreign key constraints - ** for which the renamed table is the parent table. */ - if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, - "UPDATE \"%w\".%s SET " - "sql = sqlite_rename_parent(sql, %Q, %Q) " - "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere); - sqlite3DbFree(db, zWhere); - } - } -#endif - - /* Modify the sqlite_master table to use the new table name. */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET " -#ifdef SQLITE_OMIT_TRIGGER - "sql = sqlite_rename_table(sql, %Q), " -#else - "sql = CASE " - "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" - "ELSE sqlite_rename_table(sql, %Q) END, " -#endif - "tbl_name = %Q, " - "name = CASE " - "WHEN type='table' THEN %Q " - "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " - "'sqlite_autoindex_' || %Q || substr(name,%d+18) " - "ELSE name END " - "WHERE tbl_name=%Q COLLATE nocase AND " - "(type='table' OR type='index' OR type='trigger');", - zDb, MASTER_NAME, zName, zName, zName, -#ifndef SQLITE_OMIT_TRIGGER - zName, -#endif - zName, nTabName, zTabName - ); - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* If the sqlite_sequence table exists in this database, then update - ** it with the new table name. - */ - if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ - sqlite3NestedParse(pParse, - "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", - zDb, zName, pTab->zName); - } -#endif - -#ifndef SQLITE_OMIT_TRIGGER - /* If there are TEMP triggers on this table, modify the sqlite_temp_master - ** table. Don't do this if the table being ALTERed is itself located in - ** the temp database. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, - "UPDATE sqlite_temp_master SET " - "sql = sqlite_rename_trigger(sql, %Q), " - "tbl_name = %Q " - "WHERE %s;", zName, zName, zWhere); - sqlite3DbFree(db, zWhere); - } -#endif - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - if( db->flags&SQLITE_ForeignKeys ){ - FKey *p; - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - Table *pFrom = p->pFrom; - if( pFrom!=pTab ){ - reloadTableSchema(pParse, p->pFrom, pFrom->zName); - } - } - } -#endif - - /* Drop and reload the internal table schema. */ - reloadTableSchema(pParse, pTab, zName); + renameReloadSchema(pParse, iDb); + renameTestSchema(pParse, zDb, iDb==1); exit_rename_table: sqlite3SrcListDelete(db, pSrc); @@ -600,12 +267,11 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ Column *pCol; /* The new column */ Expr *pDflt; /* Default value for the new column */ sqlite3 *db; /* The database connection; */ - Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ + Vdbe *v; /* The prepared statement under construction */ int r1; /* Temporary registers */ db = pParse->db; if( pParse->nErr || db->mallocFailed ) return; - assert( v!=0 ); pNew = pParse->pNewTable; assert( pNew ); @@ -700,17 +366,20 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ ** from less than 3 to 4, as that will corrupt any preexisting DESC ** index. */ - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); - sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); - sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); - sqlite3ReleaseTempReg(pParse, r1); + v = sqlite3GetVdbe(pParse); + if( v ){ + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); + sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); + sqlite3ReleaseTempReg(pParse, r1); + } - /* Reload the schema of the modified table. */ - reloadTableSchema(pParse, pTab, pTab->zName); + /* Reload the table definition */ + renameReloadSchema(pParse, iDb); } /* @@ -731,7 +400,6 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ Table *pNew; Table *pTab; - Vdbe *v; int iDb; int i; int nAlloc; @@ -795,14 +463,1145 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew->addColOffset = pTab->addColOffset; pNew->nTabRef = 1; - /* Begin a transaction and increment the schema cookie. */ - sqlite3BeginWriteOperation(pParse, 0, iDb); - v = sqlite3GetVdbe(pParse); - if( !v ) goto exit_begin_add_column; - sqlite3ChangeCookie(pParse, iDb); - exit_begin_add_column: sqlite3SrcListDelete(db, pSrc); return; } + +/* +** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN +** command. This function checks if the table is a view or virtual +** table (columns of views or virtual tables may not be renamed). If so, +** it loads an error message into pParse and returns non-zero. +** +** Or, if pTab is not a view or virtual table, zero is returned. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +static int isRealTable(Parse *pParse, Table *pTab){ + const char *zType = 0; +#ifndef SQLITE_OMIT_VIEW + if( pTab->pSelect ){ + zType = "view"; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + zType = "virtual table"; + } +#endif + if( zType ){ + sqlite3ErrorMsg( + pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName + ); + return 1; + } + return 0; +} +#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ +# define isRealTable(x,y) (0) +#endif + +/* +** Handles the following parser reduction: +** +** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew +*/ +void sqlite3AlterRenameColumn( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ + Token *pOld, /* Name of column being changed */ + Token *pNew /* New column name */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table being updated */ + int iCol; /* Index of column being renamed */ + char *zOld = 0; /* Old column name */ + char *zNew = 0; /* New column name */ + const char *zDb; /* Name of schema containing the table */ + int iSchema; /* Index of the schema */ + int bQuote; /* True to quote the new name */ + + /* Locate the table to be altered */ + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_rename_column; + + /* Cannot alter a system table */ + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column; + if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; + + /* Which schema holds the table to be altered */ + iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iSchema>=0 ); + zDb = db->aDb[iSchema].zDbSName; + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_column; + } +#endif + + /* Make sure the old name really is a column name in the table to be + ** altered. Set iCol to be the index of the column being renamed */ + zOld = sqlite3NameFromToken(db, pOld); + if( !zOld ) goto exit_rename_column; + for(iCol=0; iColnCol; iCol++){ + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break; + } + if( iCol==pTab->nCol ){ + sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); + goto exit_rename_column; + } + + /* Do the rename operation using a recursive UPDATE statement that + ** uses the sqlite_rename_column() SQL function to compute the new + ** CREATE statement text for the sqlite_master table. + */ + zNew = sqlite3NameFromToken(db, pNew); + if( !zNew ) goto exit_rename_column; + assert( pNew->n>0 ); + bQuote = sqlite3Isquote(pNew->z[0]); + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " + "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)" + " AND sql NOT LIKE 'create virtual%%'", + zDb, MASTER_NAME, + zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, + pTab->zName + ); + + sqlite3NestedParse(pParse, + "UPDATE temp.%s SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " + "WHERE type IN ('trigger', 'view')", + MASTER_NAME, + zDb, pTab->zName, iCol, zNew, bQuote + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iSchema); + renameTestSchema(pParse, zDb, iSchema==1); + + exit_rename_column: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zOld); + sqlite3DbFree(db, zNew); + return; +} + +/* +** Each RenameToken object maps an element of the parse tree into +** the token that generated that element. The parse tree element +** might be one of: +** +** * A pointer to an Expr that represents an ID +** * The name of a table column in Column.zName +** +** A list of RenameToken objects can be constructed during parsing. +** Each new object is created by sqlite3RenameTokenMap(). +** As the parse tree is transformed, the sqlite3RenameTokenRemap() +** routine is used to keep the mapping current. +** +** After the parse finishes, renameTokenFind() routine can be used +** to look up the actual token value that created some element in +** the parse tree. +*/ +struct RenameToken { + void *p; /* Parse tree element created by token t */ + Token t; /* The token that created parse tree element p */ + RenameToken *pNext; /* Next is a list of all RenameToken objects */ +}; + +/* +** The context of an ALTER TABLE RENAME COLUMN operation that gets passed +** down into the Walker. +*/ +typedef struct RenameCtx RenameCtx; +struct RenameCtx { + RenameToken *pList; /* List of tokens to overwrite */ + int nList; /* Number of tokens in pList */ + int iCol; /* Index of column being renamed */ + Table *pTab; /* Table being ALTERed */ + const char *zOld; /* Old column name */ +}; + +#ifdef SQLITE_DEBUG +/* +** This function is only for debugging. It performs two tasks: +** +** 1. Checks that pointer pPtr does not already appear in the +** rename-token list. +** +** 2. Dereferences each pointer in the rename-token list. +** +** The second is most effective when debugging under valgrind or +** address-sanitizer or similar. If any of these pointers no longer +** point to valid objects, an exception is raised by the memory-checking +** tool. +** +** The point of this is to prevent comparisons of invalid pointer values. +** Even though this always seems to work, it is undefined according to the +** C standard. Example of undefined comparison: +** +** sqlite3_free(x); +** if( x==y ) ... +** +** Technically, as x no longer points into a valid object or to the byte +** following a valid object, it may not be used in comparison operations. +*/ +static void renameTokenCheckAll(Parse *pParse, void *pPtr){ + if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){ + RenameToken *p; + u8 i = 0; + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p ){ + assert( p->p!=pPtr ); + i += *(u8*)(p->p); + } + } + } +} +#else +# define renameTokenCheckAll(x,y) +#endif + +/* +** Add a new RenameToken object mapping parse tree element pPtr into +** token *pToken to the Parse object currently under construction. +** +** Return a copy of pPtr. +*/ +void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){ + RenameToken *pNew; + assert( pPtr || pParse->db->mallocFailed ); + renameTokenCheckAll(pParse, pPtr); + pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); + if( pNew ){ + pNew->p = pPtr; + pNew->t = *pToken; + pNew->pNext = pParse->pRename; + pParse->pRename = pNew; + } + + return pPtr; +} + +/* +** It is assumed that there is already a RenameToken object associated +** with parse tree element pFrom. This function remaps the associated token +** to parse tree element pTo. +*/ +void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){ + RenameToken *p; + renameTokenCheckAll(pParse, pTo); + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p==pFrom ){ + p->p = pTo; + break; + } + } +} + +/* +** Walker callback used by sqlite3RenameExprUnmap(). +*/ +static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ + Parse *pParse = pWalker->pParse; + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + return WRC_Continue; +} + +/* +** Remove all nodes that are part of expression pExpr from the rename list. +*/ +void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sqlite3WalkExpr(&sWalker, pExpr); +} + +/* +** Remove all nodes that are part of expression-list pEList from the +** rename list. +*/ +void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ + if( pEList ){ + int i; + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sqlite3WalkExprList(&sWalker, pEList); + for(i=0; inExpr; i++){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName); + } + } +} + +/* +** Free the list of RenameToken objects given in the second argument +*/ +static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ + RenameToken *pNext; + RenameToken *p; + for(p=pToken; p; p=pNext){ + pNext = p->pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Search the Parse object passed as the first argument for a RenameToken +** object associated with parse tree element pPtr. If found, remove it +** from the Parse object and add it to the list maintained by the +** RenameCtx object passed as the second argument. +*/ +static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ + RenameToken **pp; + assert( pPtr!=0 ); + for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ + if( (*pp)->p==pPtr ){ + RenameToken *pToken = *pp; + *pp = pToken->pNext; + pToken->pNext = pCtx->pList; + pCtx->pList = pToken; + pCtx->nList++; + break; + } + } +} + +/* +** This is a Walker select callback. It does nothing. It is only required +** because without a dummy callback, sqlite3WalkExpr() and similar do not +** descend into sub-select statements. +*/ +static int renameColumnSelectCb(Walker *pWalker, Select *p){ + UNUSED_PARAMETER(pWalker); + UNUSED_PARAMETER(p); + return WRC_Continue; +} + +/* +** This is a Walker expression callback. +** +** For every TK_COLUMN node in the expression tree, search to see +** if the column being references is the column being renamed by an +** ALTER TABLE statement. If it is, then attach its associated +** RenameToken object to the list of RenameToken objects being +** constructed in RenameCtx object at pWalker->u.pRename. +*/ +static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_TRIGGER + && pExpr->iColumn==p->iCol + && pWalker->pParse->pTriggerTab==p->pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + }else if( pExpr->op==TK_COLUMN + && pExpr->iColumn==p->iCol + && p->pTab==pExpr->y.pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + } + return WRC_Continue; +} + +/* +** The RenameCtx contains a list of tokens that reference a column that +** is being renamed by an ALTER TABLE statement. Return the "last" +** RenameToken in the RenameCtx and remove that RenameToken from the +** RenameContext. "Last" means the last RenameToken encountered when +** the input SQL is parsed from left to right. Repeated calls to this routine +** return all column name tokens in the order that they are encountered +** in the SQL statement. +*/ +static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ + RenameToken *pBest = pCtx->pList; + RenameToken *pToken; + RenameToken **pp; + + for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){ + if( pToken->t.z>pBest->t.z ) pBest = pToken; + } + for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext); + *pp = pBest->pNext; + + return pBest; +} + +/* +** An error occured while parsing or otherwise processing a database +** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an +** ALTER TABLE RENAME COLUMN program. The error message emitted by the +** sub-routine is currently stored in pParse->zErrMsg. This function +** adds context to the error message and then stores it in pCtx. +*/ +static void renameColumnParseError( + sqlite3_context *pCtx, + int bPost, + sqlite3_value *pType, + sqlite3_value *pObject, + Parse *pParse +){ + const char *zT = (const char*)sqlite3_value_text(pType); + const char *zN = (const char*)sqlite3_value_text(pObject); + char *zErr; + + zErr = sqlite3_mprintf("error in %s %s%s: %s", + zT, zN, (bPost ? " after rename" : ""), + pParse->zErrMsg + ); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); +} + +/* +** For each name in the the expression-list pEList (i.e. each +** pEList->a[i].zName) that matches the string in zOld, extract the +** corresponding rename-token from Parse object pParse and add it +** to the RenameCtx pCtx. +*/ +static void renameColumnElistNames( + Parse *pParse, + RenameCtx *pCtx, + ExprList *pEList, + const char *zOld +){ + if( pEList ){ + int i; + for(i=0; inExpr; i++){ + char *zName = pEList->a[i].zName; + if( 0==sqlite3_stricmp(zName, zOld) ){ + renameTokenFind(pParse, pCtx, (void*)zName); + } + } + } +} + +/* +** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) +** that matches the string in zOld, extract the corresponding rename-token +** from Parse object pParse and add it to the RenameCtx pCtx. +*/ +static void renameColumnIdlistNames( + Parse *pParse, + RenameCtx *pCtx, + IdList *pIdList, + const char *zOld +){ + if( pIdList ){ + int i; + for(i=0; inId; i++){ + char *zName = pIdList->a[i].zName; + if( 0==sqlite3_stricmp(zName, zOld) ){ + renameTokenFind(pParse, pCtx, (void*)zName); + } + } + } +} + +/* +** Parse the SQL statement zSql using Parse object (*p). The Parse object +** is initialized by this function before it is used. +*/ +static int renameParseSql( + Parse *p, /* Memory to use for Parse object */ + const char *zDb, /* Name of schema SQL belongs to */ + int bTable, /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */ + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL to parse */ + int bTemp /* True if SQL is from temp schema */ +){ + int rc; + char *zErr = 0; + + db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + + /* Parse the SQL statement passed as the first argument. If no error + ** occurs and the parse does not result in a new table, index or + ** trigger object, the database must be corrupt. */ + memset(p, 0, sizeof(Parse)); + p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN); + p->db = db; + p->nQueryLoop = 1; + rc = sqlite3RunParser(p, zSql, &zErr); + assert( p->zErrMsg==0 ); + assert( rc!=SQLITE_OK || zErr==0 ); + assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 ); + p->zErrMsg = zErr; + if( db->mallocFailed ) rc = SQLITE_NOMEM; + if( rc==SQLITE_OK + && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 + ){ + rc = SQLITE_CORRUPT_BKPT; + } + +#ifdef SQLITE_DEBUG + /* Ensure that all mappings in the Parse.pRename list really do map to + ** a part of the input string. */ + if( rc==SQLITE_OK ){ + int nSql = sqlite3Strlen30(zSql); + RenameToken *pToken; + for(pToken=p->pRename; pToken; pToken=pToken->pNext){ + assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] ); + } + } +#endif + + db->init.iDb = 0; + return rc; +} + +/* +** This function edits SQL statement zSql, replacing each token identified +** by the linked list pRename with the text of zNew. If argument bQuote is +** true, then zNew is always quoted first. If no error occurs, the result +** is loaded into context object pCtx as the result. +** +** Or, if an error occurs (i.e. an OOM condition), an error is left in +** pCtx and an SQLite error code returned. +*/ +static int renameEditSql( + sqlite3_context *pCtx, /* Return result here */ + RenameCtx *pRename, /* Rename context */ + const char *zSql, /* SQL statement to edit */ + const char *zNew, /* New token text */ + int bQuote /* True to always quote token */ +){ + int nNew = sqlite3Strlen30(zNew); + int nSql = sqlite3Strlen30(zSql); + sqlite3 *db = sqlite3_context_db_handle(pCtx); + int rc = SQLITE_OK; + char *zQuot; + char *zOut; + int nQuot; + + /* Set zQuot to point to a buffer containing a quoted copy of the + ** identifier zNew. If the corresponding identifier in the original + ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to + ** point to zQuot so that all substitutions are made using the + ** quoted version of the new column name. */ + zQuot = sqlite3MPrintf(db, "\"%w\"", zNew); + if( zQuot==0 ){ + return SQLITE_NOMEM; + }else{ + nQuot = sqlite3Strlen30(zQuot); + } + if( bQuote ){ + zNew = zQuot; + nNew = nQuot; + } + + /* At this point pRename->pList contains a list of RenameToken objects + ** corresponding to all tokens in the input SQL that must be replaced + ** with the new column name. All that remains is to construct and + ** return the edited SQL string. */ + assert( nQuot>=nNew ); + zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); + if( zOut ){ + int nOut = nSql; + memcpy(zOut, zSql, nSql); + while( pRename->pList ){ + int iOff; /* Offset of token to replace in zOut */ + RenameToken *pBest = renameColumnTokenNext(pRename); + + u32 nReplace; + const char *zReplace; + if( sqlite3IsIdChar(*pBest->t.z) ){ + nReplace = nNew; + zReplace = zNew; + }else{ + nReplace = nQuot; + zReplace = zQuot; + } + + iOff = pBest->t.z - zSql; + if( pBest->t.n!=nReplace ){ + memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], + nOut - (iOff + pBest->t.n) + ); + nOut += nReplace - pBest->t.n; + zOut[nOut] = '\0'; + } + memcpy(&zOut[iOff], zReplace, nReplace); + sqlite3DbFree(db, pBest); + } + + sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT); + sqlite3DbFree(db, zOut); + }else{ + rc = SQLITE_NOMEM; + } + + sqlite3_free(zQuot); + return rc; +} + +/* +** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming +** it was read from the schema of database zDb. Return SQLITE_OK if +** successful. Otherwise, return an SQLite error code and leave an error +** message in the Parse object. +*/ +static int renameResolveTrigger(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; + Trigger *pNew = pParse->pNewTrigger; + TriggerStep *pStep; + NameContext sNC; + int rc = SQLITE_OK; + + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + assert( pNew->pTabSchema ); + pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, + db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName + ); + pParse->eTriggerOp = pNew->op; + /* ALWAYS() because if the table of the trigger does not exist, the + ** error would have been hit before this point */ + if( ALWAYS(pParse->pTriggerTab) ){ + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); + } + + /* Resolve symbols in WHEN clause */ + if( rc==SQLITE_OK && pNew->pWhen ){ + rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); + } + + for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){ + if( pStep->pSelect ){ + sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); + if( pParse->nErr ) rc = pParse->rc; + } + if( rc==SQLITE_OK && pStep->zTarget ){ + Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb); + if( pTarget==0 ){ + rc = SQLITE_ERROR; + }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){ + SrcList sSrc; + memset(&sSrc, 0, sizeof(sSrc)); + sSrc.nSrc = 1; + sSrc.a[0].zName = pStep->zTarget; + sSrc.a[0].pTab = pTarget; + sNC.pSrcList = &sSrc; + if( pStep->pWhere ){ + rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); + } + assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); + if( pStep->pUpsert ){ + Upsert *pUpsert = pStep->pUpsert; + assert( rc==SQLITE_OK ); + pUpsert->pUpsertSrc = &sSrc; + sNC.uNC.pUpsert = pUpsert; + sNC.ncFlags = NC_UUpsert; + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc==SQLITE_OK ){ + ExprList *pUpsertSet = pUpsert->pUpsertSet; + rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + } + sNC.ncFlags = 0; + } + } + } + } + return rc; +} + +/* +** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr +** objects that are part of the trigger passed as the second argument. +*/ +static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ + TriggerStep *pStep; + + /* Find tokens to edit in WHEN clause */ + sqlite3WalkExpr(pWalker, pTrigger->pWhen); + + /* Find tokens to edit in trigger steps */ + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + sqlite3WalkSelect(pWalker, pStep->pSelect); + sqlite3WalkExpr(pWalker, pStep->pWhere); + sqlite3WalkExprList(pWalker, pStep->pExprList); + if( pStep->pUpsert ){ + Upsert *pUpsert = pStep->pUpsert; + sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); + sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); + } + } +} + +/* +** Free the contents of Parse object (*pParse). Do not free the memory +** occupied by the Parse object itself. +*/ +static void renameParseCleanup(Parse *pParse){ + sqlite3 *db = pParse->db; + if( pParse->pVdbe ){ + sqlite3VdbeFinalize(pParse->pVdbe); + } + sqlite3DeleteTable(db, pParse->pNewTable); + if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex); + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + sqlite3DbFree(db, pParse->zErrMsg); + renameTokenFree(db, pParse->pRename); + sqlite3ParserReset(pParse); +} + +/* +** SQL function: +** +** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld) +** +** 0. zSql: SQL statement to rewrite +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3. Database: Database name (e.g. "main") +** 4. Table: Table name +** 5. iCol: Index of column to rename +** 6. zNew: New column name +** 7. bQuote: Non-zero if the new column name should be quoted. +** 8. bTemp: True if zSql comes from temp schema +** +** Do a column rename operation on the CREATE statement given in zSql. +** The iCol-th column (left-most is 0) of table zTable is renamed from zCol +** into zNew. The name should be quoted if bQuote is true. +** +** This function is used internally by the ALTER TABLE RENAME COLUMN command. +** Though accessible to application code, it is not intended for use by +** applications. The existance of this function, and the way it works, +** is subject to change without notice. +** +** If any of the parameters are out-of-bounds, then simply return NULL. +** An out-of-bounds parameter can only occur when the application calls +** this function directly. The parameters will always be well-formed when +** this routine is invoked by the bytecode for a legitimate ALTER TABLE +** statement. +*/ +static void renameColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + RenameCtx sCtx; + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + const char *zDb = (const char*)sqlite3_value_text(argv[3]); + const char *zTable = (const char*)sqlite3_value_text(argv[4]); + int iCol = sqlite3_value_int(argv[5]); + const char *zNew = (const char*)sqlite3_value_text(argv[6]); + int bQuote = sqlite3_value_int(argv[7]); + int bTemp = sqlite3_value_int(argv[8]); + const char *zOld; + int rc; + Parse sParse; + Walker sWalker; + Index *pIdx; + int i; + Table *pTab; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; +#endif + + UNUSED_PARAMETER(NotUsed); + if( zSql==0 ) return; + if( zTable==0 ) return; + if( zNew==0 ) return; + if( iCol<0 ) return; + sqlite3BtreeEnterAll(db); + pTab = sqlite3FindTable(db, zTable, zDb); + if( pTab==0 || iCol>=pTab->nCol ){ + sqlite3BtreeLeaveAll(db); + return; + } + zOld = pTab->aCol[iCol].zName; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp); + + /* Find tokens that need to be replaced. */ + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameColumnExprCb; + sWalker.xSelectCallback = renameColumnSelectCb; + sWalker.u.pRename = &sCtx; + + sCtx.pTab = pTab; + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + if( sParse.pNewTable ){ + Select *pSelect = sParse.pNewTable->pSelect; + if( pSelect ){ + sParse.rc = SQLITE_OK; + sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); + } + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + }else{ + /* A regular table */ + int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); + FKey *pFKey; + assert( sParse.pNewTable->pSelect==0 ); + sCtx.pTab = sParse.pNewTable; + if( bFKOnly==0 ){ + renameTokenFind( + &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName + ); + if( sCtx.iCol<0 ){ + renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); + } + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); + for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); + } + } + + for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + for(i=0; inCol; i++){ + if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ + renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); + } + if( 0==sqlite3_stricmp(pFKey->zTo, zTable) + && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) + ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol); + } + } + } + } + }else if( sParse.pNewIndex ){ + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + }else{ + /* A trigger */ + TriggerStep *pStep; + rc = renameResolveTrigger(&sParse, (bTemp ? 0 : zDb)); + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + + for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->zTarget ){ + Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); + if( pTarget==pTab ){ + if( pStep->pUpsert ){ + ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; + renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld); + } + renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld); + renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld); + } + } + } + + + /* Find tokens to edit in UPDATE OF clause */ + if( sParse.pTriggerTab==pTab ){ + renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); + } + + /* Find tokens to edit in various expressions and selects */ + renameWalkTrigger(&sWalker, sParse.pNewTrigger); + } + + assert( rc==SQLITE_OK ); + rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote); + +renameColumnFunc_done: + if( rc!=SQLITE_OK ){ + if( sParse.zErrMsg ){ + renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + sqlite3BtreeLeaveAll(db); +} + +/* +** Walker expression callback used by "RENAME TABLE". +*/ +static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){ + renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab); + } + return WRC_Continue; +} + +/* +** Walker select callback used by "RENAME TABLE". +*/ +static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ + int i; + RenameCtx *p = pWalker->u.pRename; + SrcList *pSrc = pSelect->pSrc; + for(i=0; inSrc; i++){ + struct SrcList_item *pItem = &pSrc->a[i]; + if( pItem->pTab==p->pTab ){ + renameTokenFind(pWalker->pParse, p, pItem->zName); + } + } + + return WRC_Continue; +} + + +/* +** This C function implements an SQL user function that is used by SQL code +** generated by the ALTER TABLE ... RENAME command to modify the definition +** of any foreign key constraints that use the table being renamed as the +** parent table. It is passed three arguments: +** +** 0: The database containing the table being renamed. +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3: The complete text of the schema statement being modified, +** 4: The old name of the table being renamed, and +** 5: The new name of the table being renamed. +** 6: True if the schema statement comes from the temp db. +** +** It returns the new schema statement. For example: +** +** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0) +** -> 'CREATE TABLE t1(a REFERENCES t3)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zDb = (const char*)sqlite3_value_text(argv[0]); + const char *zInput = (const char*)sqlite3_value_text(argv[3]); + const char *zOld = (const char*)sqlite3_value_text(argv[4]); + const char *zNew = (const char*)sqlite3_value_text(argv[5]); + int bTemp = sqlite3_value_int(argv[6]); + UNUSED_PARAMETER(NotUsed); + + if( zInput && zOld && zNew ){ + Parse sParse; + int rc; + int bQuote = 1; + RenameCtx sCtx; + Walker sWalker; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + sqlite3BtreeEnterAll(db); + + memset(&sCtx, 0, sizeof(RenameCtx)); + sCtx.pTab = sqlite3FindTable(db, zOld, zDb); + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameTableExprCb; + sWalker.xSelectCallback = renameTableSelectCb; + sWalker.u.pRename = &sCtx; + + rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); + + if( rc==SQLITE_OK ){ + int isLegacy = (db->flags & SQLITE_LegacyAlter); + if( sParse.pNewTable ){ + Table *pTab = sParse.pNewTable; + + if( pTab->pSelect ){ + if( isLegacy==0 ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + + sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); + if( sParse.nErr ) rc = sParse.rc; + sqlite3WalkSelect(&sWalker, pTab->pSelect); + } + }else{ + /* Modify any FK definitions to point to the new table. */ +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( db->flags & SQLITE_ForeignKeys ){ + FKey *pFKey; + for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); + } + } + } +#endif + + /* If this is the table being altered, fix any table refs in CHECK + ** expressions. Also update the name that appears right after the + ** "CREATE [VIRTUAL] TABLE" bit. */ + if( sqlite3_stricmp(zOld, pTab->zName)==0 ){ + sCtx.pTab = pTab; + if( isLegacy==0 ){ + sqlite3WalkExprList(&sWalker, pTab->pCheck); + } + renameTokenFind(&sParse, &sCtx, pTab->zName); + } + } + } + + else if( sParse.pNewIndex ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName); + if( isLegacy==0 ){ + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + } + } + +#ifndef SQLITE_OMIT_TRIGGER + else{ + Trigger *pTrigger = sParse.pNewTrigger; + TriggerStep *pStep; + if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) + && sCtx.pTab->pSchema==pTrigger->pTabSchema + ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); + } + + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb); + if( rc==SQLITE_OK ){ + renameWalkTrigger(&sWalker, pTrigger); + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ + renameTokenFind(&sParse, &sCtx, pStep->zTarget); + } + } + } + } + } +#endif + } + + if( rc==SQLITE_OK ){ + rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); + } + if( rc!=SQLITE_OK ){ + if( sParse.zErrMsg ){ + renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); + sqlite3BtreeLeaveAll(db); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + } + + return; +} + +/* +** An SQL user function that checks that there are no parse or symbol +** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement. +** After an ALTER TABLE .. RENAME operation is performed and the schema +** reloaded, this function is called on each SQL statement in the schema +** to ensure that it is still usable. +** +** 0: Database name ("main", "temp" etc.). +** 1: SQL statement. +** 2: Object type ("view", "table", "trigger" or "index"). +** 3: Object name. +** 4: True if object is from temp schema. +** +** Unless it finds an error, this function normally returns NULL. However, it +** returns integer value 1 if: +** +** * the SQL argument creates a trigger, and +** * the table that the trigger is attached to is in database zDb. +*/ +static void renameTableTest( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + int bTemp = sqlite3_value_int(argv[4]); + int isLegacy = (db->flags & SQLITE_LegacyAlter); + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + if( zDb && zInput ){ + int rc; + Parse sParse; + rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); + if( rc==SQLITE_OK ){ + if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC); + if( sParse.nErr ) rc = sParse.rc; + } + + else if( sParse.pNewTrigger ){ + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb); + } + if( rc==SQLITE_OK ){ + int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); + int i2 = sqlite3FindDbName(db, zDb); + if( i1==i2 ) sqlite3_result_int(context, 1); + } + } + } + + if( rc!=SQLITE_OK ){ + renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + } + renameParseCleanup(&sParse); + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif +} + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +void sqlite3AlterFunctions(void){ + static FuncDef aAlterTableFuncs[] = { + FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc), + FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc), + FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest), + }; + sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); +} #endif /* SQLITE_ALTER_TABLE */ diff --git a/src/analyze.c b/src/analyze.c index 6a28e16c3e..f8d69dc527 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -234,6 +234,10 @@ static void openStatTable( "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zDbSName, zTab, zWhereType, zWhere ); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + }else if( db->xPreUpdateCallback ){ + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab); +#endif }else{ /* The sqlite_stat[134] table already exists. Delete all rows. */ sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); @@ -481,6 +485,7 @@ static const FuncDef statInitFuncdef = { 0, /* pNext */ statInit, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "stat_init", /* zName */ {0} }; @@ -797,6 +802,7 @@ static const FuncDef statPushFuncdef = { 0, /* pNext */ statPush, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "stat_push", /* zName */ {0} }; @@ -948,6 +954,7 @@ static const FuncDef statGetFuncdef = { 0, /* pNext */ statGet, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "stat_get", /* zName */ {0} }; @@ -998,6 +1005,9 @@ static void analyzeOneTable( int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ int regPrev = iMem; /* MUST BE LAST (see below) */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + Table *pStat1 = 0; +#endif pParse->nMem = MAX(pParse->nMem, iMem); v = sqlite3GetVdbe(pParse); @@ -1008,7 +1018,7 @@ static void analyzeOneTable( /* Do not gather statistics on views or virtual tables */ return; } - if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ + if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){ /* Do not gather statistics on system tables */ return; } @@ -1023,6 +1033,18 @@ static void analyzeOneTable( } #endif +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( db->xPreUpdateCallback ){ + pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13); + if( pStat1==0 ) return; + pStat1->zName = (char*)&pStat1[1]; + memcpy(pStat1->zName, "sqlite_stat1", 13); + pStat1->nCol = 3; + pStat1->iPKey = -1; + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB); + } +#endif + /* Establish a read-lock on the table at the shared-cache level. ** Open a read-only cursor on the table. Also allocate a cursor number ** to use for scanning indexes (iIdxCur). No index cursor is opened at @@ -1224,6 +1246,9 @@ static void analyzeOneTable( sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); +#endif sqlite3VdbeChangeP5(v, OPFLAG_APPEND); /* Add the entries to the stat3 or stat4 table. */ @@ -1249,10 +1274,7 @@ static void analyzeOneTable( callStatGet(v, regStat4, STAT_GET_NLT, regLt); callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); - /* We know that the regSampleRowid row exists because it was read by - ** the previous loop. Thus the not-found jump of seekOp will never - ** be taken */ - VdbeCoverageNeverTaken(v); + VdbeCoverage(v); #ifdef SQLITE_ENABLE_STAT3 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample); #else @@ -1287,6 +1309,9 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); +#endif sqlite3VdbeJumpHere(v, jZeroRows); } } @@ -1890,7 +1915,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ + if( rc==SQLITE_OK ){ db->lookaside.bDisable++; rc = loadStat4(db, sInfo.zDatabase); db->lookaside.bDisable--; diff --git a/src/attach.c b/src/attach.c index 68a9a77c66..42ae536942 100644 --- a/src/attach.c +++ b/src/attach.c @@ -55,6 +55,10 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr) ** ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the ** third argument. +** +** If the db->init.reopenMemdb flags is set, then instead of attaching a +** new database, close the database on db->init.iDb and reopen it as an +** empty MemDB. */ static void attachFunc( sqlite3_context *context, @@ -75,66 +79,86 @@ static void attachFunc( sqlite3_vfs *pVfs; UNUSED_PARAMETER(NotUsed); - zFile = (const char *)sqlite3_value_text(argv[0]); zName = (const char *)sqlite3_value_text(argv[1]); if( zFile==0 ) zFile = ""; if( zName==0 ) zName = ""; - /* Check for the following errors: - ** - ** * Too many attached databases, - ** * Transaction currently open - ** * Specified database name already being used. - */ - if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ - zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", - db->aLimit[SQLITE_LIMIT_ATTACHED] - ); - goto attach_error; - } - for(i=0; inDb; i++){ - char *z = db->aDb[i].zDbSName; - assert( z && zName ); - if( sqlite3StrICmp(z, zName)==0 ){ - zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); +#ifdef SQLITE_ENABLE_DESERIALIZE +# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb) +#else +# define REOPEN_AS_MEMDB(db) (0) +#endif + + if( REOPEN_AS_MEMDB(db) ){ + /* This is not a real ATTACH. Instead, this routine is being called + ** from sqlite3_deserialize() to close database db->init.iDb and + ** reopen it as a MemDB */ + pVfs = sqlite3_vfs_find("memdb"); + if( pVfs==0 ) return; + pNew = &db->aDb[db->init.iDb]; + if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); + pNew->pBt = 0; + pNew->pSchema = 0; + rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); + }else{ + /* This is a real ATTACH + ** + ** Check for the following errors: + ** + ** * Too many attached databases, + ** * Transaction currently open + ** * Specified database name already being used. + */ + if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ + zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", + db->aLimit[SQLITE_LIMIT_ATTACHED] + ); goto attach_error; } + for(i=0; inDb; i++){ + char *z = db->aDb[i].zDbSName; + assert( z && zName ); + if( sqlite3StrICmp(z, zName)==0 ){ + zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); + goto attach_error; + } + } + + /* Allocate the new entry in the db->aDb[] array and initialize the schema + ** hash tables. + */ + if( db->aDb==db->aDbStatic ){ + aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); + if( aNew==0 ) return; + memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); + }else{ + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); + if( aNew==0 ) return; + } + db->aDb = aNew; + pNew = &db->aDb[db->nDb]; + memset(pNew, 0, sizeof(*pNew)); + + /* Open the database file. If the btree is successfully opened, use + ** it to obtain the database schema. At this point the schema may + ** or may not be initialized. + */ + flags = db->openFlags; + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + assert( pVfs ); + flags |= SQLITE_OPEN_MAIN_DB; + rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); + sqlite3_free( zPath ); + db->nDb++; } - - /* Allocate the new entry in the db->aDb[] array and initialize the schema - ** hash tables. - */ - if( db->aDb==db->aDbStatic ){ - aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); - if( aNew==0 ) return; - memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); - }else{ - aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); - if( aNew==0 ) return; - } - db->aDb = aNew; - pNew = &db->aDb[db->nDb]; - memset(pNew, 0, sizeof(*pNew)); - - /* Open the database file. If the btree is successfully opened, use - ** it to obtain the database schema. At this point the schema may - ** or may not be initialized. - */ - flags = db->openFlags; - rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); - return; - } - assert( pVfs ); - flags |= SQLITE_OPEN_MAIN_DB; - rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); - sqlite3_free( zPath ); - db->nDb++; - db->skipBtreeMutex = 0; + db->noSharedCache = 0; if( rc==SQLITE_CONSTRAINT ){ rc = SQLITE_ERROR; zErrDyn = sqlite3MPrintf(db, "database is already attached"); @@ -160,7 +184,7 @@ static void attachFunc( sqlite3BtreeLeave(pNew->pBt); } pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; - pNew->zDbSName = sqlite3DbStrDup(db, zName); + if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && pNew->zDbSName==0 ){ rc = SQLITE_NOMEM_BKPT; } @@ -200,13 +224,16 @@ static void attachFunc( /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and - ** remove the entry from the db->aDb[] array. i.e. put everything back the way - ** we found it. + ** remove the entry from the db->aDb[] array. i.e. put everything back the + ** way we found it. */ if( rc==SQLITE_OK ){ sqlite3BtreeEnterAll(db); + db->init.iDb = 0; + db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); rc = sqlite3Init(db, &zErrDyn); sqlite3BtreeLeaveAll(db); + assert( zErrDyn==0 || rc!=SQLITE_OK ); } #ifdef SQLITE_USER_AUTHENTICATION if( rc==SQLITE_OK ){ @@ -218,21 +245,23 @@ static void attachFunc( } #endif if( rc ){ - int iDb = db->nDb - 1; - assert( iDb>=2 ); - if( db->aDb[iDb].pBt ){ - sqlite3BtreeClose(db->aDb[iDb].pBt); - db->aDb[iDb].pBt = 0; - db->aDb[iDb].pSchema = 0; - } - sqlite3ResetAllSchemasOfConnection(db); - db->nDb = iDb; - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - sqlite3OomFault(db); - sqlite3DbFree(db, zErrDyn); - zErrDyn = sqlite3MPrintf(db, "out of memory"); - }else if( zErrDyn==0 ){ - zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); + if( !REOPEN_AS_MEMDB(db) ){ + int iDb = db->nDb - 1; + assert( iDb>=2 ); + if( db->aDb[iDb].pBt ){ + sqlite3BtreeClose(db->aDb[iDb].pBt); + db->aDb[iDb].pBt = 0; + db->aDb[iDb].pSchema = 0; + } + sqlite3ResetAllSchemasOfConnection(db); + db->nDb = iDb; + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + sqlite3DbFree(db, zErrDyn); + zErrDyn = sqlite3MPrintf(db, "out of memory"); + }else if( zErrDyn==0 ){ + zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); + } } goto attach_error; } @@ -385,6 +414,7 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){ 0, /* pNext */ detachFunc, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "sqlite_detach", /* zName */ {0} }; @@ -404,6 +434,7 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ 0, /* pNext */ attachFunc, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "sqlite_attach", /* zName */ {0} }; @@ -474,6 +505,9 @@ int sqlite3FixSrcList( if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; #endif + if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ + return 1; + } } return 0; } @@ -504,8 +538,13 @@ int sqlite3FixSelect( if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ return 1; } - if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ - return 1; + if( pSelect->pWith ){ + int i; + for(i=0; ipWith->nCte; i++){ + if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ + return 1; + } + } } pSelect = pSelect->pPrior; } @@ -568,6 +607,18 @@ int sqlite3FixTriggerStep( if( sqlite3FixExprList(pFix, pStep->pExprList) ){ return 1; } +#ifndef SQLITE_OMIT_UPSERT + if( pStep->pUpsert ){ + Upsert *pUp = pStep->pUpsert; + if( sqlite3FixExprList(pFix, pUp->pUpsertTarget) + || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) + || sqlite3FixExprList(pFix, pUp->pUpsertSet) + || sqlite3FixExpr(pFix, pUp->pUpsertWhere) + ){ + return 1; + } + } +#endif pStep = pStep->pNext; } return 0; diff --git a/src/auth.c b/src/auth.c index dabc435b4a..6fcdce251d 100644 --- a/src/auth.c +++ b/src/auth.c @@ -78,7 +78,7 @@ int sqlite3_set_authorizer( sqlite3_mutex_enter(db->mutex); db->xAuth = (sqlite3_xauth)xAuth; db->pAuthArg = pArg; - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -118,11 +118,9 @@ int sqlite3AuthReadCol( #endif ); if( rc==SQLITE_DENY ){ - if( db->nDb>2 || iDb!=0 ){ - sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); - }else{ - sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); - } + char *z = sqlite3_mprintf("%s.%s", zTab, zCol); + if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); + sqlite3ErrorMsg(pParse, "access to %z is prohibited", z); pParse->rc = SQLITE_AUTH; }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ sqliteAuthBadReturnCode(pParse); @@ -152,6 +150,8 @@ void sqlite3AuthRead( int iDb; /* The index of the database the expression refers to */ int iCol; /* Index of column in table */ + assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); + assert( !IN_RENAME_OBJECT || db->xAuth==0 ); if( db->xAuth==0 ) return; iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ @@ -160,7 +160,6 @@ void sqlite3AuthRead( return; } - assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); if( pExpr->op==TK_TRIGGER ){ pTab = pParse->pTriggerTab; }else{ @@ -209,7 +208,8 @@ int sqlite3AuthCheck( /* Don't do any authorization checks if the database is initialising ** or if the parser is being invoked from within sqlite3_declare_vtab. */ - if( db->init.busy || IN_DECLARE_VTAB ){ + assert( !IN_RENAME_OBJECT || db->xAuth==0 ); + if( db->init.busy || IN_SPECIAL_PARSE ){ return SQLITE_OK; } diff --git a/src/backup.c b/src/backup.c index 165144d965..4200940b24 100644 --- a/src/backup.c +++ b/src/backup.c @@ -382,7 +382,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ ** before this function exits. */ if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ - rc = sqlite3BtreeBeginTrans(p->pSrc, 0); + rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); bCloseTrans = 1; } @@ -398,10 +398,10 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ /* Lock the destination database, if it is not locked already. */ if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2, + (int*)&p->iDestSchema)) ){ p->bDestLocked = 1; - sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); } /* Do not allow backup if the destination database is in WAL mode diff --git a/src/btmutex.c b/src/btmutex.c index ddffb67fa4..275a93ff21 100644 --- a/src/btmutex.c +++ b/src/btmutex.c @@ -195,10 +195,10 @@ static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ skipOk = 0; } } - db->skipBtreeMutex = skipOk; + db->noSharedCache = skipOk; } void sqlite3BtreeEnterAll(sqlite3 *db){ - if( db->skipBtreeMutex==0 ) btreeEnterAll(db); + if( db->noSharedCache==0 ) btreeEnterAll(db); } static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){ int i; @@ -210,7 +210,7 @@ static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){ } } void sqlite3BtreeLeaveAll(sqlite3 *db){ - if( db->skipBtreeMutex==0 ) btreeLeaveAll(db); + if( db->noSharedCache==0 ) btreeLeaveAll(db); } #ifndef NDEBUG diff --git a/src/btree.c b/src/btree.c index 71e7769c1a..2fb5285474 100644 --- a/src/btree.c +++ b/src/btree.c @@ -112,6 +112,34 @@ int sqlite3_enable_shared_cache(int enable){ #define hasReadConflicts(a, b) 0 #endif +/* +** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single +** (MemPage*) as an argument. The (MemPage*) must not be NULL. +** +** If SQLITE_DEBUG is not defined, then this macro is equivalent to +** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message +** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented +** with the page number and filename associated with the (MemPage*). +*/ +#ifdef SQLITE_DEBUG +int corruptPageError(int lineno, MemPage *p){ + char *zMsg; + sqlite3BeginBenignMalloc(); + zMsg = sqlite3_mprintf("database corruption page %d of %s", + (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) + ); + sqlite3EndBenignMalloc(); + if( zMsg ){ + sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); + } + sqlite3_free(zMsg); + return SQLITE_CORRUPT_BKPT; +} +# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage) +#else +# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) +#endif + #ifndef SQLITE_OMIT_SHARED_CACHE #ifdef SQLITE_DEBUG @@ -439,7 +467,9 @@ static void downgradeAllSharedCacheTableLocks(Btree *p){ #endif /* SQLITE_OMIT_SHARED_CACHE */ -static void releasePage(MemPage *pPage); /* Forward reference */ +static void releasePage(MemPage *pPage); /* Forward reference */ +static void releasePageOne(MemPage *pPage); /* Forward reference */ +static void releasePageNotNull(MemPage *pPage); /* Forward reference */ /* ***** This routine is used inside of assert() only **** @@ -598,11 +628,13 @@ static void btreeClearHasContent(BtShared *pBt){ */ static void btreeReleaseAllCursorPages(BtCursor *pCur){ int i; - for(i=0; i<=pCur->iPage; i++){ - releasePage(pCur->apPage[i]); - pCur->apPage[i] = 0; + if( pCur->iPage>=0 ){ + for(i=0; iiPage; i++){ + releasePageNotNull(pCur->apPage[i]); + } + releasePageNotNull(pCur->pPage); + pCur->iPage = -1; } - pCur->iPage = -1; } /* @@ -771,7 +803,7 @@ static int btreeMoveto( if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); if( pIdxKey->nField==0 ){ - rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno); + rc = SQLITE_CORRUPT_BKPT; goto moveto_done; } }else{ @@ -832,7 +864,22 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){ ** back to where it ought to be if this routine returns true. */ int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ - return pCur->eState!=CURSOR_VALID; + assert( EIGHT_BYTE_ALIGNMENT(pCur) + || pCur==sqlite3BtreeFakeValidCursor() ); + assert( offsetof(BtCursor, eState)==0 ); + assert( sizeof(pCur->eState)==1 ); + return CURSOR_VALID != *(u8*)pCur; +} + +/* +** Return a pointer to a fake BtCursor object that will always answer +** false to the sqlite3BtreeCursorHasMoved() routine above. The fake +** cursor returned must not be used with any other Btree interface. +*/ +BtCursor *sqlite3BtreeFakeValidCursor(void){ + static u8 fakeCursor = CURSOR_VALID; + assert( offsetof(BtCursor, eState)==0 ); + return (BtCursor*)&fakeCursor; } /* @@ -1384,8 +1431,11 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ int sz2 = 0; int sz = get2byte(&data[iFree+2]); int top = get2byte(&data[hdr+5]); + if( top>=iFree ){ + return SQLITE_CORRUPT_PAGE(pPage); + } if( iFree2 ){ - if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */ sz2 = get2byte(&data[iFree2+2]); assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize ); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); @@ -1416,13 +1466,13 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ ** if PRAGMA cell_size_check=ON. */ if( pciCellLast ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } assert( pc>=iCellFirst && pc<=iCellLast ); size = pPage->xCellSize(pPage, &src[pc]); cbrk -= size; if( cbrkusableSize ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); testcase( cbrk+size==usableSize ); @@ -1442,7 +1492,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ defragment_out: if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } assert( cbrk>=iCellFirst ); put2byte(&data[hdr+5], cbrk); @@ -1474,16 +1524,10 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ int pc = get2byte(&aData[iAddr]); int x; int usableSize = pPg->pBt->usableSize; + int size; /* Size of the free slot */ assert( pc>0 ); - do{ - int size; /* Size of the free slot */ - /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of - ** increasing offset. */ - if( pc>usableSize-4 || pcpgno); - return 0; - } + while( pc<=usableSize-4 ){ /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each ** freeblock form a big-endian integer which is the size of the freeblock ** in bytes, including the 4-byte header. */ @@ -1491,8 +1535,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ if( (x = size - nByte)>=0 ){ testcase( x==4 ); testcase( x==3 ); - if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){ - *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno); + if( size+pc > usableSize ){ + *pRc = SQLITE_CORRUPT_PAGE(pPg); return 0; }else if( x<4 ){ /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total @@ -1512,7 +1556,11 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ } iAddr = pc; pc = get2byte(&aData[pc]); - }while( pc ); + if( pcpBt->usableSize==65536 ){ top = 65536; }else{ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } } @@ -1626,7 +1674,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ u8 hdr; /* Page header size. 0 or 100 */ u8 nFrag = 0; /* Reduction in fragmentation */ u16 iOrigSize = iSize; /* Original value of iSize */ - u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */ + u16 x; /* Offset to cell content area */ u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ @@ -1636,13 +1684,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ 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 */ - if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ - memset(&data[iStart], 0, iSize); - } + assert( iStart<=pPage->pBt->usableSize-4 ); /* The list of freeblocks must be in ascending order. Find the ** spot on the list where iStart should be inserted. @@ -1655,11 +1697,13 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ while( (iFreeBlk = get2byte(&data[iPtr]))pgno); + return SQLITE_CORRUPT_PAGE(pPage); } iPtr = iFreeBlk; } - if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + if( iFreeBlk>pPage->pBt->usableSize-4 ){ + return SQLITE_CORRUPT_PAGE(pPage); + } assert( iFreeBlk>iPtr || iFreeBlk==0 ); /* At this point: @@ -1670,10 +1714,10 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ */ if( iFreeBlk && iEnd+3>=iFreeBlk ){ nFrag = iFreeBlk - iEnd; - if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); if( iEnd > pPage->pBt->usableSize ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } iSize = iEnd - iStart; iFreeBlk = get2byte(&data[iFreeBlk]); @@ -1686,28 +1730,34 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ if( iPtr>hdr+1 ){ int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); if( iPtrEnd+3>=iStart ){ - if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage); nFrag += iStart - iPtrEnd; iSize = iEnd - iPtr; iStart = iPtr; } } - if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); data[hdr+7] -= nFrag; } - if( iStart==get2byte(&data[hdr+5]) ){ + x = get2byte(&data[hdr+5]); + if( iStart<=x ){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another ** freelist entry */ - if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + if( iStartpBt->btsFlags & BTS_FAST_SECURE ){ + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + memset(&data[iStart], 0, iSize); + } + put2byte(&data[iStart], iFreeBlk); + put2byte(&data[iStart+2], iSize); pPage->nFree += iOrigSize; return SQLITE_OK; } @@ -1767,7 +1817,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ }else{ /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is ** an error. */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } pPage->max1bytePayload = pBt->max1bytePayload; return SQLITE_OK; @@ -1808,7 +1858,7 @@ static int btreeInitPage(MemPage *pPage){ /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating ** the b-tree page type. */ if( decodeFlags(pPage, data[hdr]) ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); @@ -1827,7 +1877,7 @@ static int btreeInitPage(MemPage *pPage){ pPage->nCell = get2byte(&data[hdr+3]); if( pPage->nCell>MX_CELL(pBt) ){ /* To many cells for a single page. The page must be corrupt */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } testcase( pPage->nCell==MX_CELL(pBt) ); /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only @@ -1855,12 +1905,12 @@ static int btreeInitPage(MemPage *pPage){ testcase( pc==iCellFirst ); testcase( pc==iCellLast ); if( pciCellLast ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } sz = pPage->xCellSize(pPage, &data[pc]); testcase( pc+sz==usableSize ); if( pc+sz>usableSize ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } } if( !pPage->leaf ) iCellLast++; @@ -1878,12 +1928,12 @@ static int btreeInitPage(MemPage *pPage){ /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will ** always be at least one cell before the first freeblock. */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } while( 1 ){ if( pc>iCellLast ){ /* Freeblock off the end of the page */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } next = get2byte(&data[pc]); size = get2byte(&data[pc+2]); @@ -1893,11 +1943,11 @@ static int btreeInitPage(MemPage *pPage){ } if( next>0 ){ /* Freeblock not in ascending order */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } if( pc+size>(unsigned int)usableSize ){ /* Last freeblock extends past page end */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } } @@ -1909,7 +1959,7 @@ static int btreeInitPage(MemPage *pPage){ ** area, according to the page header, lies within the page. */ if( nFree>usableSize ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } pPage->nFree = (u16)(nFree - iCellFirst); pPage->isInit = 1; @@ -2022,7 +2072,7 @@ static Pgno btreePagecount(BtShared *pBt){ } u32 sqlite3BtreeLastPage(Btree *p){ assert( sqlite3BtreeHoldsMutex(p) ); - assert( ((p->pBt->nPage)&0x8000000)==0 ); + assert( ((p->pBt->nPage)&0x80000000)==0 ); return btreePagecount(p->pBt); } @@ -2049,7 +2099,7 @@ static int getAndInitPage( int rc; DbPage *pDbPage; assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] ); + assert( pCur==0 || ppPage==&pCur->pPage ); assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); assert( pCur==0 || pCur->iPage>0 ); @@ -2083,7 +2133,10 @@ static int getAndInitPage( return SQLITE_OK; getAndInitPage_error: - if( pCur ) pCur->iPage--; + if( pCur ){ + pCur->iPage--; + pCur->pPage = pCur->apPage[pCur->iPage]; + } testcase( pgno==0 ); assert( pgno!=0 || rc==SQLITE_CORRUPT ); return rc; @@ -2092,6 +2145,8 @@ getAndInitPage_error: /* ** Release a MemPage. This should be called once for each prior ** call to btreeGetPage. +** +** Page1 is a special case and must be released using releasePageOne(). */ static void releasePageNotNull(MemPage *pPage){ assert( pPage->aData ); @@ -2105,6 +2160,16 @@ static void releasePageNotNull(MemPage *pPage){ static void releasePage(MemPage *pPage){ if( pPage ) releasePageNotNull(pPage); } +static void releasePageOne(MemPage *pPage){ + assert( pPage!=0 ); + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefPageOne(pPage->pDbPage); +} /* ** Get an unused page. @@ -2170,7 +2235,8 @@ static int btreeInvokeBusyHandler(void *pArg){ BtShared *pBt = (BtShared*)pArg; assert( pBt->db ); assert( sqlite3_mutex_held(pBt->db->mutex) ); - return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler, + sqlite3PagerFile(pBt->pPager)); } /* @@ -2348,7 +2414,7 @@ int sqlite3BtreeOpen( } pBt->openFlags = (u8)flags; pBt->db = db; - sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); + sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); p->pBt = pBt; pBt->pCursor = 0; @@ -2889,7 +2955,8 @@ int sqlite3BtreeGetAutoVacuum(Btree *p){ ** set to the value passed to this function as the second parameter, ** set it so. */ -#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS +#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \ + && !defined(SQLITE_OMIT_WAL) static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ sqlite3 *db; Db *pDb; @@ -2909,6 +2976,10 @@ static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ # define setDefaultSyncFlag(pBt,safety_level) #endif +/* Forward declaration */ +static int newDatabase(BtShared*); + + /* ** Get a reference to pPage1 of the database file. This will ** also acquire a readlock on that file. @@ -2940,6 +3011,9 @@ static int lockBtree(BtShared *pBt){ if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ nPage = nPageFile; } + if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){ + nPage = 0; + } if( nPage>0 ){ u32 pageSize; u32 usableSize; @@ -2983,7 +3057,7 @@ static int lockBtree(BtShared *pBt){ }else{ setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1); if( isOpen==0 ){ - releasePage(pPage1); + releasePageOne(pPage1); return SQLITE_OK; } } @@ -3030,7 +3104,7 @@ static int lockBtree(BtShared *pBt){ ** zero and return SQLITE_OK. The caller will call this function ** again with the correct page-size. */ - releasePage(pPage1); + releasePageOne(pPage1); pBt->usableSize = usableSize; pBt->pageSize = pageSize; freeTempSpace(pBt); @@ -3084,7 +3158,7 @@ static int lockBtree(BtShared *pBt){ return SQLITE_OK; page1_init_failed: - releasePage(pPage1); + releasePageOne(pPage1); pBt->pPage1 = 0; return rc; } @@ -3129,7 +3203,7 @@ static void unlockBtreeIfUnused(BtShared *pBt){ assert( pPage1->aData ); assert( sqlite3PagerRefcount(pBt->pPager)==1 ); pBt->pPage1 = 0; - releasePageNotNull(pPage1); + releasePageOne(pPage1); } } @@ -3226,7 +3300,7 @@ int sqlite3BtreeNewDb(Btree *p){ ** when A already has a read lock, we encourage A to give up and let B ** proceed. */ -int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ +int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ BtShared *pBt = p->pBt; int rc = SQLITE_OK; @@ -3242,6 +3316,12 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); + if( (p->db->flags & SQLITE_ResetDatabase) + && sqlite3PagerIsreadonly(pBt->pPager)==0 + ){ + pBt->btsFlags &= ~BTS_READ_ONLY; + } + /* Write transactions are not possible on a read-only database */ if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ rc = SQLITE_READONLY; @@ -3301,6 +3381,11 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); if( rc==SQLITE_OK ){ rc = newDatabase(pBt); + }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){ + /* if there was no transaction opened when this function was + ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error + ** code to SQLITE_BUSY. */ + rc = SQLITE_BUSY; } } } @@ -3310,6 +3395,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && btreeInvokeBusyHandler(pBt) ); + sqlite3PagerResetLockTimeout(pBt->pPager); if( rc==SQLITE_OK ){ if( p->inTrans==TRANS_NONE ){ @@ -3351,14 +3437,18 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } } - trans_begun: - if( rc==SQLITE_OK && wrflag ){ - /* This call makes sure that the pager has the correct number of - ** open savepoints. If the second parameter is greater than 0 and - ** the sub-journal is not already open, then it will be opened here. - */ - rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + if( rc==SQLITE_OK ){ + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + } } btreeIntegrity(p); @@ -3424,7 +3514,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ if( eType==PTRMAP_OVERFLOW2 ){ /* The pointer is always the first 4 bytes of the page in this case. */ if( get4byte(pPage->aData)!=iFrom ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } put4byte(pPage->aData, iTo); }else{ @@ -3443,7 +3533,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ pPage->xParseCell(pPage, pCell, &info); if( info.nLocal pPage->aData+pPage->pBt->usableSize ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } if( iFrom==get4byte(pCell+info.nSize-4) ){ put4byte(pCell+info.nSize-4, iTo); @@ -3461,7 +3551,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ if( i==nCell ){ if( eType!=PTRMAP_BTREE || get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); } @@ -4051,7 +4141,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); testcase( pBt->nPage!=nPage ); pBt->nPage = nPage; - releasePage(pPage1); + releasePageOne(pPage1); } assert( countValidCursors(pBt, 1)==0 ); pBt->inTransaction = TRANS_READ; @@ -4283,7 +4373,7 @@ int sqlite3BtreeCursorSize(void){ ** of run-time by skipping the initialization of those elements. */ void sqlite3BtreeCursorZero(BtCursor *p){ - memset(p, 0, offsetof(BtCursor, iPage)); + memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT)); } /* @@ -4293,10 +4383,8 @@ void sqlite3BtreeCursorZero(BtCursor *p){ int sqlite3BtreeCloseCursor(BtCursor *pCur){ Btree *pBtree = pCur->pBtree; if( pBtree ){ - int i; BtShared *pBt = pCur->pBt; sqlite3BtreeEnter(pBtree); - sqlite3BtreeClearCursor(pCur); assert( pBt->pCursor!=0 ); if( pBt->pCursor==pCur ){ pBt->pCursor = pCur->pNext; @@ -4310,12 +4398,10 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ pPrev = pPrev->pNext; }while( ALWAYS(pPrev) ); } - for(i=0; i<=pCur->iPage; i++){ - releasePageNotNull(pCur->apPage[i]); - } + btreeReleaseAllCursorPages(pCur); unlockBtreeIfUnused(pBt); sqlite3_free(pCur->aOverflow); - /* sqlite3_free(pCur); */ + sqlite3_free(pCur->pKey); sqlite3BtreeLeave(pBtree); } return SQLITE_OK; @@ -4330,21 +4416,27 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ ** Using this cache reduces the number of calls to btreeParseCell(). */ #ifndef NDEBUG + static int cellInfoEqual(CellInfo *a, CellInfo *b){ + if( a->nKey!=b->nKey ) return 0; + if( a->pPayload!=b->pPayload ) return 0; + if( a->nPayload!=b->nPayload ) return 0; + if( a->nLocal!=b->nLocal ) return 0; + if( a->nSize!=b->nSize ) return 0; + return 1; + } static void assertCellInfo(BtCursor *pCur){ CellInfo info; - int iPage = pCur->iPage; memset(&info, 0, sizeof(info)); - btreeParseCell(pCur->apPage[iPage], pCur->ix, &info); - assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); + btreeParseCell(pCur->pPage, pCur->ix, &info); + assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) ); } #else #define assertCellInfo(x) #endif static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ if( pCur->info.nSize==0 ){ - int iPage = pCur->iPage; pCur->curFlags |= BTCF_ValidNKey; - btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info); + btreeParseCell(pCur->pPage,pCur->ix,&pCur->info); }else{ assertCellInfo(pCur); } @@ -4379,6 +4471,20 @@ i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ return pCur->info.nKey; } +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC +/* +** Return the offset into the database file for the start of the +** payload to which the cursor is pointing. +*/ +i64 sqlite3BtreeOffset(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + getCellInfo(pCur); + return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + + (i64)(pCur->info.pPayload - pCur->pPage->aData); +} +#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ + /* ** Return the number of bytes of payload for the entry that pCur is ** currently pointing to. For table btrees, this will be the amount @@ -4542,7 +4648,7 @@ static int accessPayload( unsigned char *aPayload; int rc = SQLITE_OK; int iIdx = 0; - MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ + MemPage *pPage = pCur->pPage; /* Btree page of current entry */ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ #ifdef SQLITE_DIRECT_OVERFLOW_READ unsigned char * const pBufStart = pBuf; /* Start of original out buffer */ @@ -4565,7 +4671,7 @@ static int accessPayload( ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ** but is recast into its current form to avoid integer overflow problems */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } /* Check if data must be read/written to/from the btree page itself. */ @@ -4598,14 +4704,15 @@ static int accessPayload( */ if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; - if( nOvfl>pCur->nOvflAlloc ){ + if( pCur->aOverflow==0 + || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) + ){ Pgno *aNew = (Pgno*)sqlite3Realloc( pCur->aOverflow, nOvfl*2*sizeof(Pgno) ); if( aNew==0 ){ return SQLITE_NOMEM_BKPT; }else{ - pCur->nOvflAlloc = nOvfl*2; pCur->aOverflow = aNew; } } @@ -4713,7 +4820,7 @@ static int accessPayload( if( rc==SQLITE_OK && amt>0 ){ /* Overflow chain ends prematurely */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } return rc; } @@ -4738,8 +4845,8 @@ static int accessPayload( int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->iPage>=0 && pCur->pPage ); + assert( pCur->ixpPage->nCell ); return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } @@ -4796,18 +4903,23 @@ static const void *fetchPayload( BtCursor *pCur, /* Cursor pointing to entry to read from */ u32 *pAmt /* Write the number of available bytes here */ ){ - u32 amt; - assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); + int amt; + assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage); assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorOwnsBtShared(pCur) ); - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->ixpPage->nCell ); assert( pCur->info.nSize>0 ); - assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); - assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); - amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); - if( pCur->info.nLocalinfo.nLocal; - *pAmt = amt; + assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB ); + assert( pCur->info.pPayloadpPage->aDataEnd ||CORRUPT_DB); + amt = pCur->info.nLocal; + if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){ + /* There is too little space on the page for the expected amount + ** of local content. Database must be corrupt. */ + assert( CORRUPT_DB ); + amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload)); + } + *pAmt = (u32)amt; return (void*)pCur->info.pPayload; } @@ -4852,10 +4964,11 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ } pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - pCur->aiIdx[pCur->iPage++] = pCur->ix; + pCur->aiIdx[pCur->iPage] = pCur->ix; + pCur->apPage[pCur->iPage] = pCur->pPage; pCur->ix = 0; - return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage], - pCur, pCur->curPagerFlags); + pCur->iPage++; + return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); } #ifdef SQLITE_DEBUG @@ -4889,20 +5002,23 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ ** the largest cell index. */ static void moveToParent(BtCursor *pCur){ + MemPage *pLeaf; assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>0 ); - assert( pCur->apPage[pCur->iPage] ); + assert( pCur->pPage ); assertParentIndex( pCur->apPage[pCur->iPage-1], pCur->aiIdx[pCur->iPage-1], - pCur->apPage[pCur->iPage]->pgno + pCur->pPage->pgno ); testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); pCur->ix = pCur->aiIdx[pCur->iPage-1]; - releasePageNotNull(pCur->apPage[pCur->iPage--]); + pLeaf = pCur->pPage; + pCur->pPage = pCur->apPage[--pCur->iPage]; + releasePageNotNull(pLeaf); } /* @@ -4914,9 +5030,9 @@ static void moveToParent(BtCursor *pCur){ ** single child page. This can only happen with the table rooted at page 1. ** ** If the b-tree structure is empty, the cursor state is set to -** CURSOR_INVALID. Otherwise, the cursor is set to point to the first -** cell located on the root (or virtual root) page and the cursor state -** is set to CURSOR_VALID. +** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise, +** the cursor is set to point to the first cell located on the root +** (or virtual root) page and the cursor state is set to CURSOR_VALID. ** ** If this function returns successfully, it may be assumed that the ** page-header flags indicate that the [virtual] root-page is the expected @@ -4935,18 +5051,20 @@ static int moveToRoot(BtCursor *pCur){ assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 ); + assert( pCur->pgnoRoot>0 || pCur->iPage<0 ); if( pCur->iPage>=0 ){ if( pCur->iPage ){ - do{ - assert( pCur->apPage[pCur->iPage]!=0 ); - releasePageNotNull(pCur->apPage[pCur->iPage--]); - }while( pCur->iPage); + releasePageNotNull(pCur->pPage); + while( --pCur->iPage ){ + releasePageNotNull(pCur->apPage[pCur->iPage]); + } + pCur->pPage = pCur->apPage[0]; goto skip_init; } }else if( pCur->pgnoRoot==0 ){ pCur->eState = CURSOR_INVALID; - return SQLITE_OK; + return SQLITE_EMPTY; }else{ assert( pCur->iPage==(-1) ); if( pCur->eState>=CURSOR_REQUIRESEEK ){ @@ -4956,16 +5074,16 @@ static int moveToRoot(BtCursor *pCur){ } sqlite3BtreeClearCursor(pCur); } - rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, 0, pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; - return rc; + return rc; } pCur->iPage = 0; - pCur->curIntKey = pCur->apPage[0]->intKey; + pCur->curIntKey = pCur->pPage->intKey; } - pRoot = pCur->apPage[0]; + pRoot = pCur->pPage; assert( pRoot->pgno==pCur->pgnoRoot ); /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor @@ -4980,7 +5098,7 @@ static int moveToRoot(BtCursor *pCur){ ** (or the freelist). */ assert( pRoot->intKey==1 || pRoot->intKey==0 ); if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ - return SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno); + return SQLITE_CORRUPT_PAGE(pCur->pPage); } skip_init: @@ -4988,7 +5106,7 @@ skip_init: pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); - pRoot = pCur->apPage[0]; + pRoot = pCur->pPage; if( pRoot->nCell>0 ){ pCur->eState = CURSOR_VALID; }else if( !pRoot->leaf ){ @@ -4999,6 +5117,7 @@ skip_init: rc = moveToChild(pCur, subpage); }else{ pCur->eState = CURSOR_INVALID; + rc = SQLITE_EMPTY; } return rc; } @@ -5017,7 +5136,7 @@ static int moveToLeftmost(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); - while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ assert( pCur->ixnCell ); pgno = get4byte(findCell(pPage, pCur->ix)); rc = moveToChild(pCur, pgno); @@ -5042,7 +5161,7 @@ static int moveToRightmost(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); - while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + while( !(pPage = pCur->pPage)->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); pCur->ix = pPage->nCell; rc = moveToChild(pCur, pgno); @@ -5065,18 +5184,34 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ - if( pCur->eState==CURSOR_INVALID ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - *pRes = 1; - }else{ - assert( pCur->apPage[pCur->iPage]->nCell>0 ); - *pRes = 0; - rc = moveToLeftmost(pCur); - } + assert( pCur->pPage->nCell>0 ); + *pRes = 0; + rc = moveToLeftmost(pCur); + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; } return rc; } +/* +** This function is a no-op if cursor pCur does not point to a valid row. +** Otherwise, if pCur is valid, configure it so that the next call to +** sqlite3BtreeNext() is a no-op. +*/ +#ifndef SQLITE_OMIT_WINDOWFUNC +void sqlite3BtreeSkipNext(BtCursor *pCur){ + /* We believe that the cursor must always be in the valid state when + ** this routine is called, but the proof is difficult, so we add an + ** ALWaYS() test just in case we are wrong. */ + if( ALWAYS(pCur->eState==CURSOR_VALID) ){ + pCur->eState = CURSOR_SKIPNEXT; + pCur->skipNext = 1; + } +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + /* Move the cursor to the last entry in the table. Return SQLITE_OK ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. @@ -5096,28 +5231,26 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ for(ii=0; iiiPage; ii++){ assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); } - assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 ); - assert( pCur->apPage[pCur->iPage]->leaf ); + assert( pCur->ix==pCur->pPage->nCell-1 ); + assert( pCur->pPage->leaf ); #endif return SQLITE_OK; } rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ - if( CURSOR_INVALID==pCur->eState ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - *pRes = 1; + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; }else{ - assert( pCur->eState==CURSOR_VALID ); - *pRes = 0; - rc = moveToRightmost(pCur); - if( rc==SQLITE_OK ){ - pCur->curFlags |= BTCF_AtLast; - }else{ - pCur->curFlags &= ~BTCF_AtLast; - } - + pCur->curFlags &= ~BTCF_AtLast; } + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; } return rc; } @@ -5216,22 +5349,23 @@ int sqlite3BtreeMovetoUnpacked( rc = moveToRoot(pCur); if( rc ){ + if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = -1; + return SQLITE_OK; + } return rc; } - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] ); - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit ); - assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 ); - if( pCur->eState==CURSOR_INVALID ){ - *pRes = -1; - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - return SQLITE_OK; - } - assert( pCur->apPage[0]->intKey==pCur->curIntKey ); + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); assert( pCur->curIntKey || pIdxKey ); for(;;){ int lwr, upr, idx, c; Pgno chldPg; - MemPage *pPage = pCur->apPage[pCur->iPage]; + MemPage *pPage = pCur->pPage; u8 *pCell; /* Pointer to current cell in pPage */ /* pPage->nCell must be greater than zero. If this is the root-page @@ -5254,7 +5388,7 @@ int sqlite3BtreeMovetoUnpacked( if( pPage->intKeyLeaf ){ while( 0x80 <= *(pCell++) ){ if( pCell>=pPage->aDataEnd ){ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } } } @@ -5328,7 +5462,7 @@ int sqlite3BtreeMovetoUnpacked( testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ testcase( nCell==2 ); /* Minimum legal index key size */ if( nCell<2 ){ - rc = SQLITE_CORRUPT_PGNO(pPage->pgno); + rc = SQLITE_CORRUPT_PAGE(pPage); goto moveto_finish; } pCellKey = sqlite3Malloc( nCell+18 ); @@ -5359,7 +5493,7 @@ int sqlite3BtreeMovetoUnpacked( *pRes = 0; rc = SQLITE_OK; pCur->ix = (u16)idx; - if( pIdxKey->errCode ) rc = SQLITE_CORRUPT; + if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT; goto moveto_finish; } if( lwr>upr ) break; @@ -5370,7 +5504,7 @@ int sqlite3BtreeMovetoUnpacked( assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->ixpPage->nCell ); pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; @@ -5424,9 +5558,10 @@ i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ ** opcode, and it that case the cursor will always be valid and ** will always point to a leaf node. */ if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; - if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1; + if( NEVER(pCur->pPage->leaf==0) ) return -1; - for(n=1, i=0; i<=pCur->iPage; i++){ + n = pCur->pPage->nCell; + for(i=0; iiPage; i++){ n *= pCur->apPage[i]->nCell; } return n; @@ -5479,9 +5614,18 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ } } - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; idx = ++pCur->ix; - assert( pPage->isInit ); + if( !pPage->isInit ){ + /* The only known way for this to happen is for there to be a + ** recursive SQL function that does a DELETE operation as part of a + ** SELECT which deletes content out from under an active cursor + ** in a corrupt database file where the table being DELETE-ed from + ** has pages in common with the table being queried. See TH3 + ** module cov1/btree78.test testcase 220 (2018-06-08) for an + ** example. */ + return SQLITE_CORRUPT_BKPT; + } /* If the database file is corrupt, it is possible for the value of idx ** to be invalid here. This can only occur if a second cursor modifies @@ -5502,7 +5646,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ return SQLITE_DONE; } moveToParent(pCur); - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; }while( pCur->ix>=pPage->nCell ); if( pPage->intKey ){ return sqlite3BtreeNext(pCur, 0); @@ -5525,7 +5669,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int flags){ pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur); - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; if( (++pCur->ix)>=pPage->nCell ){ pCur->ix--; return btreeNext(pCur); @@ -5584,7 +5728,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ } } - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; assert( pPage->isInit ); if( !pPage->leaf ){ int idx = pCur->ix; @@ -5603,7 +5747,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); pCur->ix--; - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; if( pPage->intKey && !pPage->leaf ){ rc = sqlite3BtreePrevious(pCur, 0); }else{ @@ -5621,7 +5765,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int flags){ pCur->info.nSize = 0; if( pCur->eState!=CURSOR_VALID || pCur->ix==0 - || pCur->apPage[pCur->iPage]->leaf==0 + || pCur->pPage->leaf==0 ){ return btreePrevious(pCur); } @@ -6108,9 +6252,8 @@ static void freePage(MemPage *pPage, int *pRC){ } /* -** Free any overflow pages associated with the given Cell. Write the -** local Cell size (the number of bytes on the original page, omitting -** overflow) into *pnSize. +** Free any overflow pages associated with the given Cell. Store +** size information about the cell in pInfo. */ static int clearCell( MemPage *pPage, /* The page that contains the Cell */ @@ -6128,9 +6271,11 @@ static int clearCell( if( pInfo->nLocal==pInfo->nPayload ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ } - if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){ + testcase( pCell + pInfo->nSize == pPage->aDataEnd ); + testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd ); + if( pCell + pInfo->nSize > pPage->aDataEnd ){ /* Cell extends past end of page */ - return SQLITE_CORRUPT_PGNO(pPage->pgno); + return SQLITE_CORRUPT_PAGE(pPage); } ovflPgno = get4byte(pCell + pInfo->nSize - 4); pBt = pPage->pBt; @@ -6201,21 +6346,20 @@ static int fillInCell( ){ int nPayload; const u8 *pSrc; - int nSrc, n, rc; + int nSrc, n, rc, mn; int spaceLeft; - MemPage *pOvfl = 0; - MemPage *pToRelease = 0; + MemPage *pToRelease; unsigned char *pPrior; unsigned char *pPayload; - BtShared *pBt = pPage->pBt; - Pgno pgnoOvfl = 0; + BtShared *pBt; + Pgno pgnoOvfl; int nHeader; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); /* pPage is not necessarily writeable since pCell might be auxiliary ** buffer space that is separate from the pPage buffer area */ - assert( pCellaData || pCell>=&pPage->aData[pBt->pageSize] + assert( pCellaData || pCell>=&pPage->aData[pPage->pBt->pageSize] || sqlite3PagerIswriteable(pPage->pDbPage) ); /* Fill in the header. */ @@ -6235,25 +6379,36 @@ static int fillInCell( } /* Fill in the payload */ + pPayload = &pCell[nHeader]; if( nPayload<=pPage->maxLocal ){ + /* This is the common case where everything fits on the btree page + ** and no overflow pages are required. */ n = nHeader + nPayload; testcase( n==3 ); testcase( n==4 ); if( n<4 ) n = 4; *pnSize = n; - spaceLeft = nPayload; - pPrior = pCell; - }else{ - int mn = pPage->minLocal; - n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); - testcase( n==pPage->maxLocal ); - testcase( n==pPage->maxLocal+1 ); - if( n > pPage->maxLocal ) n = mn; - spaceLeft = n; - *pnSize = n + nHeader + 4; - pPrior = &pCell[nHeader+n]; + assert( nSrc<=nPayload ); + testcase( nSrcminLocal; + n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); + testcase( n==pPage->maxLocal ); + testcase( n==pPage->maxLocal+1 ); + if( n > pPage->maxLocal ) n = mn; + spaceLeft = n; + *pnSize = n + nHeader + 4; + pPrior = &pCell[nHeader+n]; + pToRelease = 0; + pgnoOvfl = 0; + pBt = pPage->pBt; /* At this point variables should be set as follows: ** @@ -6279,8 +6434,35 @@ static int fillInCell( #endif /* Write the payload into the local Cell and any extra into overflow pages */ - while( nPayload>0 ){ + while( 1 ){ + n = nPayload; + if( n>spaceLeft ) n = spaceLeft; + + /* If pToRelease is not zero than pPayload points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPayload is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + if( nSrc>=n ){ + memcpy(pPayload, pSrc, n); + }else if( nSrc>0 ){ + n = nSrc; + memcpy(pPayload, pSrc, n); + }else{ + memset(pPayload, 0, n); + } + nPayload -= n; + if( nPayload<=0 ) break; + pPayload += n; + pSrc += n; + nSrc -= n; + spaceLeft -= n; if( spaceLeft==0 ){ + MemPage *pOvfl = 0; #ifndef SQLITE_OMIT_AUTOVACUUM Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ if( pBt->autoVacuum ){ @@ -6333,30 +6515,6 @@ static int fillInCell( pPayload = &pOvfl->aData[4]; spaceLeft = pBt->usableSize - 4; } - n = nPayload; - if( n>spaceLeft ) n = spaceLeft; - - /* If pToRelease is not zero than pPayload points into the data area - ** of pToRelease. Make sure pToRelease is still writeable. */ - assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); - - /* If pPayload is part of the data area of pPage, then make sure pPage - ** is still writeable */ - assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] - || sqlite3PagerIswriteable(pPage->pDbPage) ); - - if( nSrc>0 ){ - if( n>nSrc ) n = nSrc; - assert( pSrc ); - memcpy(pPayload, pSrc, n); - }else{ - memset(pPayload, 0, n); - } - nPayload -= n; - pPayload += n; - pSrc += n; - nSrc -= n; - spaceLeft -= n; } releasePage(pToRelease); return SQLITE_OK; @@ -6388,7 +6546,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ hdr = pPage->hdrOffset; testcase( pc==get2byte(&data[hdr+5]) ); testcase( pc+sz==pPage->pBt->usableSize ); - if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ + if( pc+sz > pPage->pBt->usableSize ){ *pRC = SQLITE_CORRUPT_BKPT; return; } @@ -7255,10 +7413,8 @@ static int balance_nonroot( + nMaxCells*sizeof(u16) /* b.szCell */ + pBt->pageSize; /* aSpace1 */ - /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer - ** that is more than 6 times the database page size. */ assert( szScratch<=6*(int)pBt->pageSize ); - b.apCell = sqlite3ScratchMalloc( szScratch ); + b.apCell = sqlite3StackAllocRaw(0, szScratch ); if( b.apCell==0 ){ rc = SQLITE_NOMEM_BKPT; goto balance_cleanup; @@ -7303,7 +7459,7 @@ static int balance_nonroot( } /* Load b.apCell[] with pointers to all cells in pOld. If pOld - ** constains overflow cells, include them in the b.apCell[] array + ** contains overflow cells, include them in the b.apCell[] array ** in the correct spot. ** ** Note that when there are multiple overflow cells, it is always the @@ -7836,7 +7992,7 @@ static int balance_nonroot( ** Cleanup before returning. */ balance_cleanup: - sqlite3ScratchFree(b.apCell); + sqlite3StackFree(0, b.apCell); for(i=0; iiPage; - MemPage *pPage = pCur->apPage[iPage]; + MemPage *pPage = pCur->pPage; if( iPage==0 ){ if( pPage->nOverflow ){ @@ -7951,7 +8107,9 @@ static int balance(BtCursor *pCur){ pCur->iPage = 1; pCur->ix = 0; pCur->aiIdx[0] = 0; - assert( pCur->apPage[1]->nOverflow ); + pCur->apPage[0] = pPage; + pCur->pPage = pCur->apPage[1]; + assert( pCur->pPage->nOverflow ); } }else{ break; @@ -8031,6 +8189,7 @@ static int balance(BtCursor *pCur){ releasePage(pPage); pCur->iPage--; assert( pCur->iPage>=0 ); + pCur->pPage = pCur->apPage[pCur->iPage]; } }while( rc==SQLITE_OK ); @@ -8040,6 +8199,94 @@ static int balance(BtCursor *pCur){ return rc; } +/* Overwrite content from pX into pDest. Only do the write if the +** content is different from what is already there. +*/ +static int btreeOverwriteContent( + MemPage *pPage, /* MemPage on which writing will occur */ + u8 *pDest, /* Pointer to the place to start writing */ + const BtreePayload *pX, /* Source of data to write */ + int iOffset, /* Offset of first byte to write */ + int iAmt /* Number of bytes to be written */ +){ + int nData = pX->nData - iOffset; + if( nData<=0 ){ + /* Overwritting with zeros */ + int i; + for(i=0; ipDbPage); + if( rc ) return rc; + memset(pDest + i, 0, iAmt - i); + } + }else{ + if( nDatapData) + iOffset, iAmt)!=0 ){ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt); + } + } + return SQLITE_OK; +} + +/* +** Overwrite the cell that cursor pCur is pointing to with fresh content +** contained in pX. +*/ +static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ + int iOffset; /* Next byte of pX->pData to write */ + int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ + int rc; /* Return code */ + MemPage *pPage = pCur->pPage; /* Page being written */ + BtShared *pBt; /* Btree */ + Pgno ovflPgno; /* Next overflow page to write */ + u32 ovflPageSize; /* Size to write on overflow page */ + + if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + /* Overwrite the local portion first */ + rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, + 0, pCur->info.nLocal); + if( rc ) return rc; + if( pCur->info.nLocal==nTotal ) return SQLITE_OK; + + /* Now overwrite the overflow pages */ + iOffset = pCur->info.nLocal; + assert( nTotal>=0 ); + assert( iOffset>=0 ); + ovflPgno = get4byte(pCur->info.pPayload + iOffset); + pBt = pPage->pBt; + ovflPageSize = pBt->usableSize - 4; + do{ + rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); + if( rc ) return rc; + if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + if( iOffset+ovflPageSize<(u32)nTotal ){ + ovflPgno = get4byte(pPage->aData); + }else{ + ovflPageSize = nTotal - iOffset; + } + rc = btreeOverwriteContent(pPage, pPage->aData+4, pX, + iOffset, ovflPageSize); + } + sqlite3PagerUnref(pPage->pDbPage); + if( rc ) return rc; + iOffset += ovflPageSize; + }while( iOffsetpgnoRoot, pX->nKey, 0); /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing - ** to a row with the same key as the new entry being inserted. */ - assert( (flags & BTREE_SAVEPOSITION)==0 || - ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); + ** to a row with the same key as the new entry being inserted. + */ +#ifdef SQLITE_DEBUG + if( flags & BTREE_SAVEPOSITION ){ + assert( pCur->curFlags & BTCF_ValidNKey ); + assert( pX->nKey==pCur->info.nKey ); + assert( pCur->info.nSize!=0 ); + assert( loc==0 ); + } +#endif - /* If the cursor is currently on the last row and we are appending a - ** new row onto the end, set the "loc" to avoid an unnecessary - ** btreeMoveto() call */ + /* On the other hand, BTREE_SAVEPOSITION==0 does not imply + ** that the cursor is not pointing to a row to be overwritten. + ** So do a complete check. + */ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ - loc = 0; + /* The cursor is pointing to the entry that is to be + ** overwritten */ + assert( pX->nData>=0 && pX->nZero>=0 ); + if( pCur->info.nSize!=0 + && pCur->info.nPayload==(u32)pX->nData+pX->nZero + ){ + /* New entry is the same size as the old. Do an overwrite */ + return btreeOverwriteCell(pCur, pX); + } + assert( loc==0 ); }else if( loc==0 ){ + /* The cursor is *not* pointing to the cell to be overwritten, nor + ** to an adjacent cell. Move the cursor so that it is pointing either + ** to the cell to be overwritten or an adjacent cell. + */ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } - }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ - if( pX->nMem ){ - UnpackedRecord r; - r.pKeyInfo = pCur->pKeyInfo; - r.aMem = pX->aMem; - r.nField = pX->nMem; - r.default_rc = 0; - r.errCode = 0; - r.r1 = 0; - r.r2 = 0; - r.eqSeen = 0; - rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); - }else{ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); + }else{ + /* This is an index or a WITHOUT ROWID table */ + + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + ** to a row with the same key as the new entry being inserted. + */ + assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 ); + + /* If the cursor is not already pointing either to the cell to be + ** overwritten, or if a new cell is being inserted, if the cursor is + ** not pointing to an immediately adjacent cell, then move the cursor + ** so that it does. + */ + if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ + if( pX->nMem ){ + UnpackedRecord r; + r.pKeyInfo = pCur->pKeyInfo; + r.aMem = pX->aMem; + r.nField = pX->nMem; + r.default_rc = 0; + r.errCode = 0; + r.r1 = 0; + r.r2 = 0; + r.eqSeen = 0; + rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); + }else{ + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); + } + if( rc ) return rc; } - if( rc ) return rc; + + /* If the cursor is currently pointing to an entry to be overwritten + ** and the new content is the same as as the old, then use the + ** overwrite optimization. + */ + if( loc==0 ){ + getCellInfo(pCur); + if( pCur->info.nKey==pX->nKey ){ + BtreePayload x2; + x2.pData = pX->pKey; + x2.nData = pX->nKey; + x2.nZero = 0; + return btreeOverwriteCell(pCur, &x2); + } + } + } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); @@ -8249,7 +8547,7 @@ int sqlite3BtreeInsert( ** fails. Internal data structure corruption will result otherwise. ** Also, set the cursor state to invalid. This stops saveCursorPosition() ** from trying to save the current position of the cursor. */ - pCur->apPage[pCur->iPage]->nOverflow = 0; + pCur->pPage->nOverflow = 0; pCur->eState = CURSOR_INVALID; if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){ btreeReleaseAllCursorPages(pCur); @@ -8266,7 +8564,7 @@ int sqlite3BtreeInsert( pCur->nKey = pX->nKey; } } - assert( pCur->iPage<0 || pCur->apPage[pCur->iPage]->nOverflow==0 ); + assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 ); end_insert: return rc; @@ -8307,13 +8605,13 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( pCur->curFlags & BTCF_WriteFlag ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->ixpPage->nCell ); assert( pCur->eState==CURSOR_VALID ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); iCellDepth = pCur->iPage; iCellIdx = pCur->ix; - pPage = pCur->apPage[iCellDepth]; + pPage = pCur->pPage; pCell = findCell(pPage, iCellIdx); /* If the bPreserve flag is set to true, then the cursor position must @@ -8379,11 +8677,16 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** node. The cell from the leaf node needs to be moved to the internal ** node to replace the deleted cell. */ if( !pPage->leaf ){ - MemPage *pLeaf = pCur->apPage[pCur->iPage]; + MemPage *pLeaf = pCur->pPage; int nCell; - Pgno n = pCur->apPage[iCellDepth+1]->pgno; + Pgno n; unsigned char *pTmp; + if( iCellDepthiPage-1 ){ + n = pCur->apPage[iCellDepth+1]->pgno; + }else{ + n = pCur->pPage->pgno; + } pCell = findCell(pLeaf, pLeaf->nCell-1); if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; nCell = pLeaf->xCellSize(pLeaf, pCell); @@ -8415,16 +8718,19 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** well. */ rc = balance(pCur); if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + releasePageNotNull(pCur->pPage); + pCur->iPage--; while( pCur->iPage>iCellDepth ){ releasePage(pCur->apPage[pCur->iPage--]); } + pCur->pPage = pCur->apPage[pCur->iPage]; rc = balance(pCur); } if( rc==SQLITE_OK ){ if( bSkipnext ){ assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); - assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB ); + assert( pPage==pCur->pPage || CORRUPT_DB ); assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); pCur->eState = CURSOR_SKIPNEXT; if( iCellIdx>=pPage->nCell ){ @@ -8439,6 +8745,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ btreeReleaseAllCursorPages(pCur); pCur->eState = CURSOR_REQUIRESEEK; } + if( rc==SQLITE_EMPTY ) rc = SQLITE_OK; } } return rc; @@ -8903,11 +9210,11 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ i64 nEntry = 0; /* Value to return in *pnEntry */ int rc; /* Return code */ - if( pCur->pgnoRoot==0 ){ + rc = moveToRoot(pCur); + if( rc==SQLITE_EMPTY ){ *pnEntry = 0; return SQLITE_OK; } - rc = moveToRoot(pCur); /* Unless an error occurs, the following loop runs one iteration for each ** page in the B-Tree structure (not including overflow pages). @@ -8920,7 +9227,7 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ ** this page contains countable entries. Increment the entry counter ** accordingly. */ - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; if( pPage->leaf || !pPage->intKey ){ nEntry += pPage->nCell; } @@ -8943,10 +9250,10 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ return moveToRoot(pCur); } moveToParent(pCur); - }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell ); + }while ( pCur->ix>=pCur->pPage->nCell ); pCur->ix++; - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; } /* Descend to the child node of the cell that the cursor currently @@ -8988,14 +9295,14 @@ static void checkAppendMsg( pCheck->nErr++; va_start(ap, zFormat); if( pCheck->errMsg.nChar ){ - sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); + sqlite3_str_append(&pCheck->errMsg, "\n", 1); } if( pCheck->zPfx ){ - sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); + sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); } - sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap); + sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); va_end(ap); - if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ + if( pCheck->errMsg.accError==SQLITE_NOMEM ){ pCheck->mallocFailed = 1; } } @@ -9030,8 +9337,7 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ - if( iPage==0 ) return 1; - if( iPage>pCheck->nPage ){ + if( iPage>pCheck->nPage || iPage==0 ){ checkAppendMsg(pCheck, "invalid page number %d", iPage); return 1; } @@ -9086,17 +9392,12 @@ static void checkList( ){ int i; int expected = N; - int iFirst = iPage; - while( N-- > 0 && pCheck->mxErr ){ + int nErrAtStart = pCheck->nErr; + while( iPage!=0 && pCheck->mxErr ){ DbPage *pOvflPage; unsigned char *pOvflData; - if( iPage<1 ){ - checkAppendMsg(pCheck, - "%d of %d pages missing from overflow list starting at %d", - N+1, expected, iFirst); - break; - } if( checkRef(pCheck, iPage) ) break; + N--; if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ checkAppendMsg(pCheck, "failed to get page %d", iPage); break; @@ -9140,10 +9441,12 @@ static void checkList( #endif iPage = get4byte(pOvflData); sqlite3PagerUnref(pOvflPage); - - if( isFreeList && N<(iPage!=0) ){ - checkAppendMsg(pCheck, "free-page count in header is too small"); - } + } + if( N && nErrAtStart==pCheck->nErr ){ + checkAppendMsg(pCheck, + "%s is %d but should be %d", + isFreeList ? "size" : "overflow list length", + expected-N, expected); } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -9537,6 +9840,24 @@ char *sqlite3BtreeIntegrityCheck( /* Check all the tables. */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + int mx = 0; + int mxInHdr; + for(i=0; (int)ipPage1->aData[52]); + if( mx!=mxInHdr ){ + checkAppendMsg(&sCheck, + "max rootpage (%d) disagrees with header (%d)", + mx, mxInHdr + ); + } + }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){ + checkAppendMsg(&sCheck, + "incremental_vacuum enabled with a max rootpage of zero" + ); + } +#endif testcase( pBt->db->flags & SQLITE_CellSizeCk ); pBt->db->flags &= ~SQLITE_CellSizeCk; for(i=0; (int)ipPager) ); sqlite3BtreeLeave(p); @@ -9787,7 +10108,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ && pCsr->pBt->inTransaction==TRANS_WRITE ); assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); - assert( pCsr->apPage[pCsr->iPage]->intKey ); + assert( pCsr->pPage->intKey ); return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); } @@ -9818,11 +10139,11 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ pBt->btsFlags &= ~BTS_NO_WAL; if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; - rc = sqlite3BtreeBeginTrans(pBtree, 0); + rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); if( rc==SQLITE_OK ){ u8 *aData = pBt->pPage1->aData; if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ - rc = sqlite3BtreeBeginTrans(pBtree, 2); + rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc==SQLITE_OK ){ diff --git a/src/btree.h b/src/btree.h index b56eb85e68..f6cf55bad9 100644 --- a/src/btree.h +++ b/src/btree.h @@ -78,7 +78,7 @@ int sqlite3BtreeGetOptimalReserve(Btree*); int sqlite3BtreeGetReserveNoMutex(Btree *p); int sqlite3BtreeSetAutoVacuum(Btree *, int); int sqlite3BtreeGetAutoVacuum(Btree *); -int sqlite3BtreeBeginTrans(Btree*,int); +int sqlite3BtreeBeginTrans(Btree*,int,int*); int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); int sqlite3BtreeCommitPhaseTwo(Btree*, int); int sqlite3BtreeCommit(Btree*); @@ -230,6 +230,7 @@ int sqlite3BtreeCursor( struct KeyInfo*, /* First argument to compare function */ BtCursor *pCursor /* Space to write cursor structure */ ); +BtCursor *sqlite3BtreeFakeValidCursor(void); int sqlite3BtreeCursorSize(void); void sqlite3BtreeCursorZero(BtCursor*); void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); @@ -258,13 +259,28 @@ int sqlite3BtreeDelete(BtCursor*, u8 flags); ** entry in either an index or table btree. ** ** Index btrees (used for indexes and also WITHOUT ROWID tables) contain -** an arbitrary key and no data. These btrees have pKey,nKey set to their -** key and pData,nData,nZero set to zero. +** an arbitrary key and no data. These btrees have pKey,nKey set to the +** key and the pData,nData,nZero fields are uninitialized. The aMem,nMem +** fields give an array of Mem objects that are a decomposition of the key. +** The nMem field might be zero, indicating that no decomposition is available. ** ** Table btrees (used for rowid tables) contain an integer rowid used as ** the key and passed in the nKey field. The pKey field is zero. ** pData,nData hold the content of the new entry. nZero extra zero bytes ** are appended to the end of the content when constructing the entry. +** The aMem,nMem fields are uninitialized for table btrees. +** +** Field usage summary: +** +** Table BTrees Index Btrees +** +** pKey always NULL encoded key +** nKey the ROWID length of pKey +** pData data not used +** aMem not used decomposed key value +** nMem not used entries in aMem +** nData length of pData not used +** nZero extra zeros after pData not used ** ** This object is used to pass information into sqlite3BtreeInsert(). The ** same information used to be passed as five separate parameters. But placing @@ -275,7 +291,7 @@ int sqlite3BtreeDelete(BtCursor*, u8 flags); struct BtreePayload { const void *pKey; /* Key content for indexes. NULL for tables */ sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ - const void *pData; /* Data for tables. NULL for indexes */ + const void *pData; /* Data for tables. */ sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */ u16 nMem; /* Number of aMem[] value. Might be zero */ int nData; /* Size of pData. 0 if none. */ @@ -285,11 +301,17 @@ struct BtreePayload { int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, int flags, int seekResult); int sqlite3BtreeFirst(BtCursor*, int *pRes); +#ifndef SQLITE_OMIT_WINDOWFUNC +void sqlite3BtreeSkipNext(BtCursor*); +#endif int sqlite3BtreeLast(BtCursor*, int *pRes); int sqlite3BtreeNext(BtCursor*, int flags); int sqlite3BtreeEof(BtCursor*); int sqlite3BtreePrevious(BtCursor*, int flags); i64 sqlite3BtreeIntegerKey(BtCursor*); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC +i64 sqlite3BtreeOffset(BtCursor*); +#endif int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); u32 sqlite3BtreePayloadSize(BtCursor*); diff --git a/src/btreeInt.h b/src/btreeInt.h index 77069783c7..d1e2c08d18 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -499,30 +499,31 @@ struct CellInfo { ** eState==FAULT: Cursor fault with skipNext as error code. */ struct BtCursor { - Btree *pBtree; /* The Btree to which this cursor belongs */ - BtShared *pBt; /* The BtShared this cursor points to */ - BtCursor *pNext; /* Forms a linked list of all cursors */ - Pgno *aOverflow; /* Cache of overflow page locations */ - CellInfo info; /* A parse of the cell we are pointing at */ - i64 nKey; /* Size of pKey, or last integer key */ - void *pKey; /* Saved key that was cursor last known position */ - Pgno pgnoRoot; /* The root page of this tree */ - int nOvflAlloc; /* Allocated size of aOverflow[] array */ - int skipNext; /* Prev() is noop if negative. Next() is noop if positive. - ** Error code if eState==CURSOR_FAULT */ + u8 eState; /* One of the CURSOR_XXX constants (see below) */ u8 curFlags; /* zero or more BTCF_* flags defined below */ u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ - u8 eState; /* One of the CURSOR_XXX constants (see below) */ u8 hints; /* As configured by CursorSetHints() */ + int skipNext; /* Prev() is noop if negative. Next() is noop if positive. + ** Error code if eState==CURSOR_FAULT */ + Btree *pBtree; /* The Btree to which this cursor belongs */ + Pgno *aOverflow; /* Cache of overflow page locations */ + void *pKey; /* Saved key that was cursor last known position */ /* All fields above are zeroed when the cursor is allocated. See ** sqlite3BtreeCursorZero(). Fields that follow must be manually ** initialized. */ +#define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */ + BtShared *pBt; /* The BtShared this cursor points to */ + BtCursor *pNext; /* Forms a linked list of all cursors */ + CellInfo info; /* A parse of the cell we are pointing at */ + i64 nKey; /* Size of pKey, or last integer key */ + Pgno pgnoRoot; /* The root page of this tree */ i8 iPage; /* Index of current page in apPage */ u8 curIntKey; /* Value of apPage[0]->intKey */ u16 ix; /* Current index for apPage[iPage] */ u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ - MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ + MemPage *pPage; /* Current page */ + MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */ }; /* @@ -565,8 +566,8 @@ struct BtCursor { ** Do nothing else with this cursor. Any attempt to use the cursor ** should return the error code stored in BtCursor.skipNext */ -#define CURSOR_INVALID 0 -#define CURSOR_VALID 1 +#define CURSOR_VALID 0 +#define CURSOR_INVALID 1 #define CURSOR_SKIPNEXT 2 #define CURSOR_REQUIRESEEK 3 #define CURSOR_FAULT 4 diff --git a/src/build.c b/src/build.c index f60f3a62b1..ed09564460 100644 --- a/src/build.c +++ b/src/build.c @@ -225,7 +225,6 @@ void sqlite3FinishCoding(Parse *pParse){ /* Get the VDBE program ready for execution */ if( v && pParse->nErr==0 && !db->mallocFailed ){ - assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; @@ -343,24 +342,27 @@ Table *sqlite3LocateTable( const char *zDbase /* Name of the database. Might be NULL */ ){ Table *p; + sqlite3 *db = pParse->db; /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 + && SQLITE_OK!=sqlite3ReadSchema(pParse) + ){ return 0; } - p = sqlite3FindTable(pParse->db, zName, zDbase); + p = sqlite3FindTable(db, zName, zDbase); if( p==0 ){ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; #ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3FindDbName(pParse->db, zDbase)<1 ){ + if( sqlite3FindDbName(db, zDbase)<1 ){ /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ - Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName); + Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ - pMod = sqlite3PragmaVtabRegister(pParse->db, zName); + pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ return pMod->pEpoTab; @@ -437,7 +439,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ /* ** Reclaim the memory used by an index */ -static void freeIndex(sqlite3 *db, Index *p){ +void sqlite3FreeIndex(sqlite3 *db, Index *p){ #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif @@ -477,7 +479,7 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ p->pNext = pIndex->pNext; } } - freeIndex(db, pIndex); + sqlite3FreeIndex(db, pIndex); } db->mDbFlags |= DBFLAG_SchemaChange; } @@ -514,24 +516,30 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){ /* ** Reset the schema for the database at index iDb. Also reset the -** TEMP schema. +** TEMP schema. The reset is deferred if db->nSchemaLock is not zero. +** Deferred resets may be run by calling with iDb<0. */ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ - /* If any database other than TEMP is reset, then also reset TEMP - ** since TEMP might be holding triggers that reference tables in the - ** other database. */ - Db *pDb = &db->aDb[1]; - assert( pDb->pSchema!=0 ); - sqlite3SchemaClear(pDb->pSchema); - + int i; assert( iDbnDb ); - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - assert( db->aDb[iDb].pSchema!=0 ); - if( iDb!=1 ){ - sqlite3SchemaUnuse(db, iDb); + if( iDb>=0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + DbSetProperty(db, iDb, DB_ResetWanted); + DbSetProperty(db, 1, DB_ResetWanted); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; + } + if( db->nSchemaLock==0 ){ + for(i=0; inDb; i++){ + if( DbHasProperty(db, i, DB_ResetWanted) ){ + if( i==1 ){ + sqlite3SchemaClear(db->aDb[1].pSchema); + }else{ + sqlite3SchemaUnuse(db, i); + } + } + } } - return; } /* @@ -541,12 +549,12 @@ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ int i; sqlite3BtreeEnterAll(db); - for(i=0; inDb; i = (i?i+1:2)){ + assert( db->nSchemaLock==0 ); + for(i=0; inDb; i=(i?i+1:2)){ sqlite3SchemaUnuse(db, i); } sqlite3SchemaClear(db->aDb[1].pSchema); - - db->mDbFlags &= ~DBFLAG_SchemaChange; + db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk); sqlite3VtabUnlockList(db); sqlite3BtreeLeaveAll(db); sqlite3CollapseDatabaseArray(db); @@ -594,13 +602,16 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ */ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ Index *pIndex, *pNext; - TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */ +#ifdef SQLITE_DEBUG /* Record the number of outstanding lookaside allocations in schema Tables ** prior to doing any free() operations. Since schema Tables do not use ** lookaside, this number should not change. */ - TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ? - db->lookaside.nOut : 0 ); + int nLookaside = 0; + if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){ + nLookaside = sqlite3LookasideUsed(db, 0); + } +#endif /* Delete all indices associated with this table. */ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ @@ -615,7 +626,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); assert( pOld==pIndex || pOld==0 ); } - freeIndex(db, pIndex); + sqlite3FreeIndex(db, pIndex); } /* Delete any foreign keys attached to this table. */ @@ -634,7 +645,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ sqlite3DbFree(db, pTable); /* Verify that no lookaside memory was used by schema tables */ - assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); + assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); } void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Do not delete the table until the reference count reaches zero. */ @@ -773,7 +784,7 @@ int sqlite3TwoPartName( return -1; } }else{ - assert( db->init.iDb==0 || db->init.busy + assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT || (db->mDbFlags & DBFLAG_Vacuum)!=0); iDb = db->init.iDb; *pUnqual = pName1; @@ -868,6 +879,9 @@ void sqlite3StartTable( } if( !OMIT_TEMPDB && isTemp ) iDb = 1; zName = sqlite3NameFromToken(db, pName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)zName, pName); + } } pParse->sNameToken = *pName; if( zName==0 ) return; @@ -903,7 +917,7 @@ void sqlite3StartTable( ** and types will be used, so there is no need to test for namespace ** collisions. */ - if( !IN_DECLARE_VTAB ){ + if( !IN_SPECIAL_PARSE ){ char *zDb = db->aDb[iDb].zDbSName; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; @@ -1006,7 +1020,8 @@ void sqlite3StartTable( }else #endif { - pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2); + pParse->addrCrTab = + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } sqlite3OpenMasterTable(pParse, iDb); sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); @@ -1055,14 +1070,13 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ Column *pCol; sqlite3 *db = pParse->db; if( (p = pParse->pNewTable)==0 ) return; -#if SQLITE_MAX_COLUMN if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); return; } -#endif z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); if( z==0 ) return; + if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName); memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); @@ -1089,15 +1103,20 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ if( pType->n==0 ){ /* If there is no type specified, columns have the default affinity - ** 'BLOB'. */ + ** 'BLOB' with a default size of 4 bytes. */ pCol->affinity = SQLITE_AFF_BLOB; pCol->szEst = 1; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( 4>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } +#endif }else{ zType = z + sqlite3Strlen30(z) + 1; memcpy(zType, pType->z, pType->n); zType[pType->n] = 0; sqlite3Dequote(zType); - pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); + pCol->affinity = sqlite3AffinityType(zType, pCol); pCol->colFlags |= COLFLAG_HASTYPE; } p->nCol++; @@ -1112,10 +1131,24 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ */ void sqlite3AddNotNull(Parse *pParse, int onError){ Table *p; + Column *pCol; p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; - p->aCol[p->nCol-1].notNull = (u8)onError; + pCol = &p->aCol[p->nCol-1]; + pCol->notNull = (u8)onError; p->tabFlags |= TF_HasNotNull; + + /* Set the uniqNotNull flag on any UNIQUE or PK indexes already created + ** on this column. */ + if( pCol->colFlags & COLFLAG_UNIQUE ){ + Index *pIdx; + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None ); + if( pIdx->aiColumn[0]==p->nCol-1 ){ + pIdx->uniqNotNull = 1; + } + } + } } /* @@ -1143,7 +1176,7 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ ** If none of the substrings in the above table are found, ** SQLITE_AFF_NUMERIC is returned. */ -char sqlite3AffinityType(const char *zIn, u8 *pszEst){ +char sqlite3AffinityType(const char *zIn, Column *pCol){ u32 h = 0; char aff = SQLITE_AFF_NUMERIC; const char *zChar = 0; @@ -1180,27 +1213,32 @@ char sqlite3AffinityType(const char *zIn, u8 *pszEst){ } } - /* If pszEst is not NULL, store an estimate of the field size. The + /* If pCol is not NULL, store an estimate of the field size. The ** estimate is scaled so that the size of an integer is 1. */ - if( pszEst ){ - *pszEst = 1; /* default size is approx 4 bytes */ + if( pCol ){ + int v = 0; /* default size is approx 4 bytes */ if( aff r=(k/4+1) */ sqlite3GetInt32(zChar, &v); - v = v/4 + 1; - if( v>255 ) v = 255; - *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */ break; } zChar++; } }else{ - *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ + v = 16; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ } } +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( v>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } +#endif + v = v/4 + 1; + if( v>255 ) v = 255; + pCol->szEst = v; } return aff; } @@ -1215,34 +1253,40 @@ char sqlite3AffinityType(const char *zIn, u8 *pszEst){ ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. */ -void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){ +void sqlite3AddDefaultValue( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The parsed expression of the default value */ + const char *zStart, /* Start of the default value text */ + const char *zEnd /* First character past end of defaut value text */ +){ Table *p; Column *pCol; sqlite3 *db = pParse->db; p = pParse->pNewTable; if( p!=0 ){ pCol = &(p->aCol[p->nCol-1]); - if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){ + if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); }else{ /* A copy of pExpr is used instead of the original, as pExpr contains - ** tokens that point to volatile memory. The 'span' of the expression - ** is required by pragma table_info. + ** tokens that point to volatile memory. */ Expr x; sqlite3ExprDelete(db, pCol->pDflt); memset(&x, 0, sizeof(x)); x.op = TK_SPAN; - x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart, - (int)(pSpan->zEnd - pSpan->zStart)); - x.pLeft = pSpan->pExpr; + x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); + x.pLeft = pExpr; x.flags = EP_Skip; pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); sqlite3DbFree(db, x.u.zToken); } } - sqlite3ExprDelete(db, pSpan->pExpr); + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprUnmap(pParse, pExpr); + } + sqlite3ExprDelete(db, pExpr); } /* @@ -1333,6 +1377,9 @@ void sqlite3AddPrimaryKey( && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 && sortOrder!=SQLITE_SO_DESC ){ + if( IN_RENAME_OBJECT && pList ){ + sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr); + } pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); @@ -1473,7 +1520,7 @@ void sqlite3ChangeCookie(Parse *pParse, int iDb){ Vdbe *v = pParse->pVdbe; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, - db->aDb[iDb].pSchema->schema_cookie+1); + (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie)); } /* @@ -1658,6 +1705,31 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ return 0; } +/* Recompute the colNotIdxed field of the Index. +** +** colNotIdxed is a bitmask that has a 0 bit representing each indexed +** columns that are within the first 63 columns of the table. The +** high-order bit of colNotIdxed is always 1. All unindexed columns +** of the table have a 1. +** +** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask +** to determine if the index is covering index. +*/ +static void recomputeColumnsNotIndexed(Index *pIdx){ + Bitmask m = 0; + int j; + for(j=pIdx->nColumn-1; j>=0; j--){ + int x = pIdx->aiColumn[j]; + if( x>=0 ){ + testcase( x==BMS-1 ); + testcase( x==BMS-2 ); + if( xcolNotIdxed = ~m; + assert( (pIdx->colNotIdxed>>63)==1 ); +} + /* ** This routine runs at the end of parsing a CREATE TABLE statement that ** has a WITHOUT ROWID clause. The job of this routine is to convert both @@ -1666,9 +1738,8 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ ** Changes include: ** ** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. -** (2) Convert the OP_CreateTable into an OP_CreateIndex. There is -** no rowid btree for a WITHOUT ROWID. Instead, the canonical -** data storage is a covering index btree. +** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY +** into BTREE_BLOBKEY. ** (3) Bypass the creation of the sqlite_master table entry ** for the PRIMARY KEY as the primary key index is now ** identified by the sqlite_master table entry of the table itself. @@ -1701,17 +1772,12 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ } } - /* The remaining transformations only apply to b-tree tables, not to - ** virtual tables */ - if( IN_DECLARE_VTAB ) return; - - /* Convert the OP_CreateTable opcode that would normally create the - ** root-page for the table into an OP_CreateIndex opcode. The index - ** created will become the PRIMARY KEY index. + /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY + ** into BTREE_BLOBKEY. */ if( pParse->addrCrTab ){ assert( v ); - sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex); + sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); } /* Locate the PRIMARY KEY index. Or, if this table was originally @@ -1728,7 +1794,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ assert( pParse->pNewTable==pTab ); sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); - if( db->mallocFailed ) return; + if( db->mallocFailed || pParse->nErr ) return; pPk = sqlite3PrimaryKeyIndex(pTab); pTab->iPKey = -1; }else{ @@ -1808,6 +1874,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ }else{ pPk->nColumn = pTab->nCol; } + recomputeColumnsNotIndexed(pPk); } /* @@ -1849,8 +1916,6 @@ void sqlite3EndTable( p = pParse->pNewTable; if( p==0 ) return; - assert( !db->init.busy || !pSelect ); - /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" or "sqlite_temp_master" table on the disk. ** So do not write to the disk again. Extract the root page number @@ -1861,6 +1926,10 @@ void sqlite3EndTable( ** table itself. So mark it read-only. */ if( db->init.busy ){ + if( pSelect ){ + sqlite3ErrorMsg(pParse, ""); + return; + } p->tnum = db->init.newTnum; if( p->tnum==1 ) p->tabFlags |= TF_Readonly; } @@ -1961,10 +2030,6 @@ void sqlite3EndTable( pParse->nTab = 2; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); - sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); - sqlite3Select(pParse, pSelect, &dest); - sqlite3VdbeEndCoroutine(v, regYield); - sqlite3VdbeJumpHere(v, addrTop - 1); if( pParse->nErr ) return; pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect); if( pSelTab==0 ) return; @@ -1974,6 +2039,11 @@ void sqlite3EndTable( pSelTab->nCol = 0; pSelTab->aCol = 0; sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + sqlite3Select(pParse, pSelect, &dest); + if( pParse->nErr ) return; + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); @@ -2108,7 +2178,12 @@ void sqlite3CreateView( ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ - p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + p->pSelect = pSelect; + pSelect = 0; + }else{ + p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); if( db->mallocFailed ) goto create_view_fail; @@ -2116,7 +2191,7 @@ void sqlite3CreateView( ** the end. */ sEnd = pParse->sLastToken; - assert( sEnd.z[0]!=0 ); + assert( sEnd.z[0]!=0 || sEnd.n==0 ); if( sEnd.z[0]!=';' ){ sEnd.z += sEnd.n; } @@ -2133,6 +2208,9 @@ void sqlite3CreateView( create_view_fail: sqlite3SelectDelete(db, pSelect); + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprlistUnmap(pParse, pCNames); + } sqlite3ExprListDelete(db, pCNames); return; } @@ -2150,6 +2228,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int rc; +#endif #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth; /* Saved xAuth pointer */ #endif @@ -2157,8 +2238,11 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3VtabCallConnect(pParse, pTable) ){ - return SQLITE_ERROR; + db->nSchemaLock++; + rc = sqlite3VtabCallConnect(pParse, pTable); + db->nSchemaLock--; + if( rc ){ + return 1; } if( IsVirtual(pTable) ) return 0; #endif @@ -2200,6 +2284,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable->pSelect ); pSel = sqlite3SelectDup(db, pTable->pSelect, 0); if( pSel ){ +#ifndef SQLITE_OMIT_ALTERTABLE + u8 eParseMode = pParse->eParseMode; + pParse->eParseMode = PARSE_MODE_NORMAL; +#endif n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; @@ -2245,10 +2333,18 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ sqlite3DeleteTable(db, pSelTab); sqlite3SelectDelete(db, pSel); db->lookaside.bDisable--; +#ifndef SQLITE_OMIT_ALTERTABLE + pParse->eParseMode = eParseMode; +#endif } else { nErr++; } pTable->pSchema->schemaFlags |= DB_UnresetViews; + if( db->mallocFailed ){ + sqlite3DeleteColumnNames(db, pTable); + pTable->aCol = 0; + pTable->nCol = 0; + } #endif /* SQLITE_OMIT_VIEW */ return nErr; } @@ -2354,14 +2450,6 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ ** is also added (this can happen with an auto-vacuum database). */ static void destroyTable(Parse *pParse, Table *pTab){ -#ifdef SQLITE_OMIT_AUTOVACUUM - Index *pIdx; - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - destroyRootPage(pParse, pTab->tnum, iDb); - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - destroyRootPage(pParse, pIdx->tnum, iDb); - } -#else /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM ** is not defined), then it is important to call OP_Destroy on the ** table and index root-pages in order, starting with the numerically @@ -2404,7 +2492,6 @@ static void destroyTable(Parse *pParse, Table *pTab){ iDestroyed = iLargest; } } -#endif } /* @@ -2597,8 +2684,10 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ v = sqlite3GetVdbe(pParse); if( v ){ sqlite3BeginWriteOperation(pParse, 1, iDb); - sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); - sqlite3FkDropTable(pParse, pName, pTab); + if( !isView ){ + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + sqlite3FkDropTable(pParse, pName, pTab); + } sqlite3CodeDropTable(pParse, pTab, iDb, isView); } @@ -2673,6 +2762,9 @@ void sqlite3CreateForeignKey( pFKey->pNextFrom = p->pFKey; z = (char*)&pFKey->aCol[nCol]; pFKey->zTo = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)z, pTo); + } memcpy(z, pTo->z, pTo->n); z[pTo->n] = 0; sqlite3Dequote(z); @@ -2695,12 +2787,18 @@ void sqlite3CreateForeignKey( pFromCol->a[i].zName); goto fk_end; } + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName); + } } } if( pToCol ){ for(i=0; ia[i].zName); pFKey->aCol[i].zCol = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName); + } memcpy(z, pToCol->a[i].zName, n); z[n] = 0; z += n+1; @@ -2809,6 +2907,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); regRecord = sqlite3GetTempReg(pParse); + sqlite3MultiWrite(pParse); sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); @@ -2822,12 +2921,13 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); if( IsUniqueIndex(pIndex) ){ - int j2 = sqlite3VdbeCurrentAddr(v) + 3; - sqlite3VdbeGoto(v, j2); + int j2 = sqlite3VdbeGoto(v, 1); addr2 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyAbortable(v, OE_Abort); sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, pIndex->nKeyCol); VdbeCoverage(v); sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); + sqlite3VdbeJumpHere(v, j2); }else{ addr2 = sqlite3VdbeCurrentAddr(v); } @@ -2990,7 +3090,11 @@ void sqlite3CreateIndex( #if SQLITE_USER_AUTHENTICATION && sqlite3UserAuthTable(pTab->zName)==0 #endif - && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){ +#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX + && sqlite3StrICmp(&pTab->zName[7],"master")!=0 +#endif + && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 + ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } @@ -3027,21 +3131,23 @@ void sqlite3CreateIndex( if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto exit_create_index; } - if( !db->init.busy ){ - if( sqlite3FindTable(db, zName, 0)!=0 ){ - sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + if( !IN_RENAME_OBJECT ){ + if( !db->init.busy ){ + if( sqlite3FindTable(db, zName, 0)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + goto exit_create_index; + } + } + if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } goto exit_create_index; } } - if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ - if( !ifNotExist ){ - sqlite3ErrorMsg(pParse, "index %s already exists", zName); - }else{ - assert( !db->init.busy ); - sqlite3CodeVerifySchema(pParse, iDb); - } - goto exit_create_index; - } }else{ int n; Index *pLoop; @@ -3056,13 +3162,13 @@ void sqlite3CreateIndex( ** The following statement converts "sqlite3_autoindex..." into ** "sqlite3_butoindex..." in order to make the names distinct. ** The "vtab_err.test" test demonstrates the need of this statement. */ - if( IN_DECLARE_VTAB ) zName[7]++; + if( IN_SPECIAL_PARSE ) zName[7]++; } /* Check for authorization to create an index. */ #ifndef SQLITE_OMIT_AUTHORIZATION - { + if( !IN_RENAME_OBJECT ){ const char *zDb = pDb->zDbSName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ goto exit_create_index; @@ -3081,7 +3187,9 @@ void sqlite3CreateIndex( */ if( pList==0 ){ Token prevCol; - sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName); + Column *pCol = &pTab->aCol[pTab->nCol-1]; + pCol->colFlags |= COLFLAG_UNIQUE; + sqlite3TokenInit(&prevCol, pCol->zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; @@ -3147,7 +3255,12 @@ void sqlite3CreateIndex( ** TODO: Issue a warning if the table primary key is used as part of the ** index key. */ - for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){ + pListItem = pList->a; + if( IN_RENAME_OBJECT ){ + pIndex->aColExpr = pList; + pList = 0; + } + for(i=0; inKeyCol; i++, pListItem++){ Expr *pCExpr; /* The i-th index expression */ int requestedSortOrder; /* ASC or DESC on the i-th expression */ const char *zColl; /* Collation sequence name */ @@ -3163,12 +3276,8 @@ void sqlite3CreateIndex( goto exit_create_index; } if( pIndex->aColExpr==0 ){ - ExprList *pCopy = sqlite3ExprListDup(db, pList, 0); - pIndex->aColExpr = pCopy; - if( !db->mallocFailed ){ - assert( pCopy!=0 ); - pListItem = &pCopy->a[i]; - } + pIndex->aColExpr = pList; + pList = 0; } j = XN_EXPR; pIndex->aiColumn[i] = XN_EXPR; @@ -3234,6 +3343,7 @@ void sqlite3CreateIndex( ** it as a covering index */ assert( HasRowid(pTab) || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 ); + recomputeColumnsNotIndexed(pIndex); if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ pIndex->isCovering = 1; for(j=0; jnCol; j++){ @@ -3306,98 +3416,101 @@ void sqlite3CreateIndex( } } - /* Link the new Index structure to its table and to the other - ** in-memory database structures. - */ - assert( pParse->nErr==0 ); - if( db->init.busy ){ - Index *p; - assert( !IN_DECLARE_VTAB ); - assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); - p = sqlite3HashInsert(&pIndex->pSchema->idxHash, - pIndex->zName, pIndex); - if( p ){ - assert( p==pIndex ); /* Malloc must have failed */ - sqlite3OomFault(db); - goto exit_create_index; - } - db->mDbFlags |= DBFLAG_SchemaChange; - if( pTblName!=0 ){ - pIndex->tnum = db->init.newTnum; - } - } + if( !IN_RENAME_OBJECT ){ - /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the - ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then - ** emit code to allocate the index rootpage on disk and make an entry for - ** the index in the sqlite_master table and populate the index with - ** content. But, do not do this if we are simply reading the sqlite_master - ** table to parse the schema, or if this index is the PRIMARY KEY index - ** of a WITHOUT ROWID table. - ** - ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY - ** or UNIQUE index in a CREATE TABLE statement. Since the table - ** has just been created, it contains no data and the index initialization - ** step can be skipped. - */ - else if( HasRowid(pTab) || pTblName!=0 ){ - 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 + /* Link the new Index structure to its table and to the other + ** in-memory database structures. */ - if( pStart ){ - int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; - if( pName->z[n-1]==';' ) n--; - /* A named index with an explicit CREATE INDEX statement */ - zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", - onError==OE_None ? "" : " UNIQUE", n, pName->z); - }else{ - /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ - /* zStmt = sqlite3MPrintf(""); */ - zStmt = 0; + assert( pParse->nErr==0 ); + if( db->init.busy ){ + Index *p; + assert( !IN_SPECIAL_PARSE ); + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + pIndex->zName, pIndex); + if( p ){ + assert( p==pIndex ); /* Malloc must have failed */ + sqlite3OomFault(db); + goto exit_create_index; + } + db->mDbFlags |= DBFLAG_SchemaChange; + if( pTblName!=0 ){ + pIndex->tnum = db->init.newTnum; + } } - /* Add an entry in sqlite_master for this index + /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the + ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then + ** emit code to allocate the index rootpage on disk and make an entry for + ** the index in the sqlite_master table and populate the index with + ** content. But, do not do this if we are simply reading the sqlite_master + ** table to parse the schema, or if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table. + ** + ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY + ** or UNIQUE index in a CREATE TABLE statement. Since the table + ** has just been created, it contains no data and the index initialization + ** step can be skipped. */ - sqlite3NestedParse(pParse, - "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zDbSName, MASTER_NAME, - pIndex->zName, - pTab->zName, - iMem, - zStmt - ); - sqlite3DbFree(db, zStmt); + else if( HasRowid(pTab) || pTblName!=0 ){ + Vdbe *v; + char *zStmt; + int iMem = ++pParse->nMem; - /* Fill the index with data and reparse the schema. Code an OP_Expire - ** to invalidate all pre-compiled statements. - */ - if( pTblName ){ - sqlite3RefillIndex(pParse, pIndex, iMem); - sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddParseSchemaOp(pParse, iDb, - sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); - sqlite3VdbeAddOp0(v, OP_Expire); + 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); + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); + + /* 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( pName->z[n-1]==';' ) n--; + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", n, pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; + } + + /* Add an entry in sqlite_master for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zDbSName, MASTER_NAME, + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); + sqlite3DbFree(db, zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ + if( pTblName ){ + sqlite3RefillIndex(pParse, pIndex, iMem); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(pParse, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); + } + + sqlite3VdbeJumpHere(v, pIndex->tnum); } - - sqlite3VdbeJumpHere(v, pIndex->tnum); } /* When adding an index to the list of indices for a table, make @@ -3421,10 +3534,15 @@ void sqlite3CreateIndex( } pIndex = 0; } + else if( IN_RENAME_OBJECT ){ + assert( pParse->pNewIndex==0 ); + pParse->pNewIndex = pIndex; + pIndex = 0; + } /* Clean up before exiting */ exit_create_index: - if( pIndex ) freeIndex(db, pIndex); + if( pIndex ) sqlite3FreeIndex(db, pIndex); sqlite3ExprDelete(db, pPIWhere); sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); @@ -3594,7 +3712,8 @@ void *sqlite3ArrayAllocate( ** ** A new IdList is returned, or NULL if malloc() fails. */ -IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ +IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ + sqlite3 *db = pParse->db; int i; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(IdList) ); @@ -3612,6 +3731,9 @@ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ return 0; } pList->a[i].zName = sqlite3NameFromToken(db, pToken); + if( IN_RENAME_OBJECT && pList->a[i].zName ){ + sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); + } return pList; } @@ -3853,10 +3975,17 @@ SrcList *sqlite3SrcListAppendFromTerm( goto append_from_error; } p = sqlite3SrcListAppend(db, p, pTable, pDatabase); - if( p==0 || NEVER(p->nSrc==0) ){ + if( p==0 ){ goto append_from_error; } + assert( p->nSrc>0 ); pItem = &p->a[p->nSrc-1]; + assert( (pTable==0)==(pDatabase==0) ); + assert( pItem->zName==0 || pDatabase!=0 ); + if( IN_RENAME_OBJECT && pItem->zName ){ + Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; + sqlite3RenameTokenMap(pParse, pItem->zName, pToken); + } assert( pAlias!=0 ); if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); @@ -3880,8 +4009,10 @@ SrcList *sqlite3SrcListAppendFromTerm( */ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ assert( pIndexedBy!=0 ); - if( p && ALWAYS(p->nSrc>0) ){ - struct SrcList_item *pItem = &p->a[p->nSrc-1]; + if( p && pIndexedBy->n>0 ){ + struct SrcList_item *pItem; + assert( p->nSrc>0 ); + pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); assert( pItem->fg.isTabFunc==0 ); @@ -3891,7 +4022,7 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ pItem->fg.notIndexed = 1; }else{ pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); - pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0); + pItem->fg.isIndexedBy = 1; } } } @@ -4165,16 +4296,16 @@ void sqlite3UniqueConstraint( sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); if( pIdx->aColExpr ){ - sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName); + sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName); }else{ for(j=0; jnKeyCol; j++){ char *zCol; assert( pIdx->aiColumn[j]>=0 ); zCol = pTab->aCol[pIdx->aiColumn[j]].zName; - if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); - sqlite3StrAccumAppendAll(&errMsg, pTab->zName); - sqlite3StrAccumAppend(&errMsg, ".", 1); - sqlite3StrAccumAppendAll(&errMsg, zCol); + if( j ) sqlite3_str_append(&errMsg, ", ", 2); + sqlite3_str_appendall(&errMsg, pTab->zName); + sqlite3_str_append(&errMsg, ".", 1); + sqlite3_str_appendall(&errMsg, zCol); } } zErr = sqlite3StrAccumFinish(&errMsg); @@ -4362,6 +4493,18 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ pKey->aSortOrder[i] = pIdx->aSortOrder[i]; } if( pParse->nErr ){ + assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ ); + if( pIdx->bNoQuery==0 ){ + /* Deactivate the index because it contains an unknown collating + ** sequence. The only way to reactive the index is to reload the + ** schema. Adding the missing collating sequence later does not + ** reactive the index. The application had the chance to register + ** the missing index using the collation-needed callback. For + ** simplicity, SQLite will not give the application a second chance. + */ + pIdx->bNoQuery = 1; + pParse->rc = SQLITE_ERROR_RETRY; + } sqlite3KeyInfoUnref(pKey); pKey = 0; } diff --git a/src/callback.c b/src/callback.c index 217c83a031..ed3e47f296 100644 --- a/src/callback.c +++ b/src/callback.c @@ -105,6 +105,7 @@ CollSeq *sqlite3GetCollSeq( assert( !p || p->xCmp ); if( p==0 ){ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; } return p; } @@ -405,10 +406,12 @@ FuncDef *sqlite3FindFunction( if( createFlag && bestScorezName = (const char*)&pBest[1]; pBest->nArg = (u16)nArg; pBest->funcFlags = enc; memcpy((char*)&pBest[1], zName, nName+1); + for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z]; pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); if( pOther==pBest ){ sqlite3DbFree(db, pBest); @@ -457,8 +460,8 @@ void sqlite3SchemaClear(void *p){ pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ pSchema->iGeneration++; - pSchema->schemaFlags &= ~DB_SchemaLoaded; } + pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); } /* diff --git a/src/ctime.c b/src/ctime.c index e8f4e7f90b..f408a3b5f0 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -30,6 +30,12 @@ #define CTIMEOPT_VAL_(opt) #opt #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) +/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This +** option requires a separate macro because legal values contain a single +** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */ +#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2 +#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt) + /* ** An array of names of all compile-time options. This array should ** be sorted A-Z. @@ -113,7 +119,7 @@ static const char * const sqlite3azCompileOpt[] = { "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), #endif #ifdef SQLITE_DEFAULT_LOOKASIDE - "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE), + "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE), #endif #if SQLITE_DEFAULT_MEMSTATUS "DEFAULT_MEMSTATUS", @@ -188,7 +194,7 @@ static const char * const sqlite3azCompileOpt[] = { "ENABLE_BATCH_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_CEROD - "ENABLE_CEROD", + "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), #endif #if SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", @@ -286,6 +292,9 @@ static const char * const sqlite3azCompileOpt[] = { #if SQLITE_ENABLE_SNAPSHOT "ENABLE_SNAPSHOT", #endif +#if SQLITE_ENABLE_SORTER_REFERENCES + "ENABLE_SORTER_REFERENCES", +#endif #if SQLITE_ENABLE_SQLLOG "ENABLE_SQLLOG", #endif diff --git a/src/date.c b/src/date.c index c0ca4c9904..313c7f9137 100644 --- a/src/date.c +++ b/src/date.c @@ -39,7 +39,7 @@ ** ** Jean Meeus ** Astronomical Algorithms, 2nd Edition, 1998 -** ISBM 0-943396-61-1 +** ISBN 0-943396-61-1 ** Willmann-Bell, Inc ** Richmond, Virginia (USA) */ diff --git a/src/dbpage.c b/src/dbpage.c new file mode 100644 index 0000000000..5b19abd356 --- /dev/null +++ b/src/dbpage.c @@ -0,0 +1,411 @@ +/* +** 2017-10-11 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains an implementation of the "sqlite_dbpage" virtual table. +** +** The sqlite_dbpage virtual table is used to read or write whole raw +** pages of the database file. The pager interface is used so that +** uncommitted changes and changes recorded in the WAL file are correctly +** retrieved. +** +** Usage example: +** +** SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123; +** +** This is an eponymous virtual table so it does not need to be created before +** use. The optional argument to the sqlite_dbpage() table name is the +** schema for the database file that is to be read. The default schema is +** "main". +** +** The data field of sqlite_dbpage table can be updated. The new +** value must be a BLOB which is the correct page size, otherwise the +** update fails. Rows may not be deleted or inserted. +*/ + +#include "sqliteInt.h" /* Requires access to internal data structures */ +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) + +typedef struct DbpageTable DbpageTable; +typedef struct DbpageCursor DbpageCursor; + +struct DbpageCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + int pgno; /* Current page number */ + int mxPgno; /* Last page to visit on this scan */ + Pager *pPager; /* Pager being read/written */ + DbPage *pPage1; /* Page 1 of the database */ + int iDb; /* Index of database to analyze */ + int szPage; /* Size of each page in bytes */ +}; + +struct DbpageTable { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database */ +}; + +/* Columns */ +#define DBPAGE_COLUMN_PGNO 0 +#define DBPAGE_COLUMN_DATA 1 +#define DBPAGE_COLUMN_SCHEMA 2 + + + +/* +** Connect to or create a dbpagevfs virtual table. +*/ +static int dbpageConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + DbpageTable *pTab = 0; + int rc = SQLITE_OK; + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); + if( rc==SQLITE_OK ){ + pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable)); + if( pTab==0 ) rc = SQLITE_NOMEM_BKPT; + } + + assert( rc==SQLITE_OK || pTab==0 ); + if( rc==SQLITE_OK ){ + memset(pTab, 0, sizeof(DbpageTable)); + pTab->db = db; + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Disconnect from or destroy a dbpagevfs virtual table. +*/ +static int dbpageDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** idxNum: +** +** 0 schema=main, full table scan +** 1 schema=main, pgno=?1 +** 2 schema=?1, full table scan +** 3 schema=?1, pgno=?2 +*/ +static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int i; + int iPlan = 0; + + /* If there is a schema= constraint, it must be honored. Report a + ** ridiculously large estimated cost if the schema= constraint is + ** unavailable + */ + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue; + if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( !p->usable ){ + /* No solution. Use the default SQLITE_BIG_DBL cost */ + pIdxInfo->estimatedRows = 0x7fffffff; + return SQLITE_OK; + } + iPlan = 2; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + break; + } + + /* If we reach this point, it means that either there is no schema= + ** constraint (in which case we use the "main" schema) or else the + ** schema constraint was accepted. Lower the estimated cost accordingly + */ + pIdxInfo->estimatedCost = 1.0e6; + + /* Check for constraints against pgno */ + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; + pIdxInfo->estimatedCost = 1.0; + pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + iPlan |= 1; + break; + } + } + pIdxInfo->idxNum = iPlan; + + if( pIdxInfo->nOrderBy>=1 + && pIdxInfo->aOrderBy[0].iColumn<=0 + && pIdxInfo->aOrderBy[0].desc==0 + ){ + pIdxInfo->orderByConsumed = 1; + } + return SQLITE_OK; +} + +/* +** Open a new dbpagevfs cursor. +*/ +static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + DbpageCursor *pCsr; + + pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM_BKPT; + }else{ + memset(pCsr, 0, sizeof(DbpageCursor)); + pCsr->base.pVtab = pVTab; + pCsr->pgno = -1; + } + + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Close a dbpagevfs cursor. +*/ +static int dbpageClose(sqlite3_vtab_cursor *pCursor){ + DbpageCursor *pCsr = (DbpageCursor *)pCursor; + if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Move a dbpagevfs cursor to the next entry in the file. +*/ +static int dbpageNext(sqlite3_vtab_cursor *pCursor){ + int rc = SQLITE_OK; + DbpageCursor *pCsr = (DbpageCursor *)pCursor; + pCsr->pgno++; + return rc; +} + +static int dbpageEof(sqlite3_vtab_cursor *pCursor){ + DbpageCursor *pCsr = (DbpageCursor *)pCursor; + return pCsr->pgno > pCsr->mxPgno; +} + +/* +** idxNum: +** +** 0 schema=main, full table scan +** 1 schema=main, pgno=?1 +** 2 schema=?1, full table scan +** 3 schema=?1, pgno=?2 +** +** idxStr is not used +*/ +static int dbpageFilter( + sqlite3_vtab_cursor *pCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + DbpageCursor *pCsr = (DbpageCursor *)pCursor; + DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; + int rc; + sqlite3 *db = pTab->db; + Btree *pBt; + + /* Default setting is no rows of result */ + pCsr->pgno = 1; + pCsr->mxPgno = 0; + + if( idxNum & 2 ){ + const char *zSchema; + assert( argc>=1 ); + zSchema = (const char*)sqlite3_value_text(argv[0]); + pCsr->iDb = sqlite3FindDbName(db, zSchema); + if( pCsr->iDb<0 ) return SQLITE_OK; + }else{ + pCsr->iDb = 0; + } + pBt = db->aDb[pCsr->iDb].pBt; + if( pBt==0 ) return SQLITE_OK; + pCsr->pPager = sqlite3BtreePager(pBt); + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); + pCsr->mxPgno = sqlite3BtreeLastPage(pBt); + if( idxNum & 1 ){ + assert( argc>(idxNum>>1) ); + pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]); + if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){ + pCsr->pgno = 1; + pCsr->mxPgno = 0; + }else{ + pCsr->mxPgno = pCsr->pgno; + } + }else{ + assert( pCsr->pgno==1 ); + } + if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); + rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0); + return rc; +} + +static int dbpageColumn( + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, + int i +){ + DbpageCursor *pCsr = (DbpageCursor *)pCursor; + int rc = SQLITE_OK; + switch( i ){ + case 0: { /* pgno */ + sqlite3_result_int(ctx, pCsr->pgno); + break; + } + case 1: { /* data */ + DbPage *pDbPage = 0; + rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); + if( rc==SQLITE_OK ){ + sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, + SQLITE_TRANSIENT); + } + sqlite3PagerUnref(pDbPage); + break; + } + default: { /* schema */ + sqlite3 *db = sqlite3_context_db_handle(ctx); + sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC); + break; + } + } + return SQLITE_OK; +} + +static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + DbpageCursor *pCsr = (DbpageCursor *)pCursor; + *pRowid = pCsr->pgno; + return SQLITE_OK; +} + +static int dbpageUpdate( + sqlite3_vtab *pVtab, + int argc, + sqlite3_value **argv, + sqlite_int64 *pRowid +){ + DbpageTable *pTab = (DbpageTable *)pVtab; + Pgno pgno; + DbPage *pDbPage = 0; + int rc = SQLITE_OK; + char *zErr = 0; + const char *zSchema; + int iDb; + Btree *pBt; + Pager *pPager; + int szPage; + + if( argc==1 ){ + zErr = "cannot delete"; + goto update_fail; + } + pgno = sqlite3_value_int(argv[0]); + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ + zErr = "cannot insert"; + goto update_fail; + } + zSchema = (const char*)sqlite3_value_text(argv[4]); + iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1; + if( iDb<0 ){ + zErr = "no such schema"; + goto update_fail; + } + pBt = pTab->db->aDb[iDb].pBt; + if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){ + zErr = "bad page number"; + goto update_fail; + } + szPage = sqlite3BtreeGetPageSize(pBt); + if( sqlite3_value_type(argv[3])!=SQLITE_BLOB + || sqlite3_value_bytes(argv[3])!=szPage + ){ + zErr = "bad page value"; + goto update_fail; + } + pPager = sqlite3BtreePager(pBt); + rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pDbPage); + if( rc==SQLITE_OK ){ + memcpy(sqlite3PagerGetData(pDbPage), + sqlite3_value_blob(argv[3]), + szPage); + } + } + sqlite3PagerUnref(pDbPage); + return rc; + +update_fail: + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = sqlite3_mprintf("%s", zErr); + return SQLITE_ERROR; +} + +/* Since we do not know in advance which database files will be +** written by the sqlite_dbpage virtual table, start a write transaction +** on them all. +*/ +static int dbpageBegin(sqlite3_vtab *pVtab){ + DbpageTable *pTab = (DbpageTable *)pVtab; + sqlite3 *db = pTab->db; + int i; + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); + } + return SQLITE_OK; +} + + +/* +** Invoke this routine to register the "dbpage" virtual table module +*/ +int sqlite3DbpageRegister(sqlite3 *db){ + static sqlite3_module dbpage_module = { + 0, /* iVersion */ + dbpageConnect, /* xCreate */ + dbpageConnect, /* xConnect */ + dbpageBestIndex, /* xBestIndex */ + dbpageDisconnect, /* xDisconnect */ + dbpageDisconnect, /* xDestroy */ + dbpageOpen, /* xOpen - open a cursor */ + dbpageClose, /* xClose - close a cursor */ + dbpageFilter, /* xFilter - configure scan constraints */ + dbpageNext, /* xNext - advance a cursor */ + dbpageEof, /* xEof - check for end of scan */ + dbpageColumn, /* xColumn - read data */ + dbpageRowid, /* xRowid - read data */ + dbpageUpdate, /* xUpdate */ + dbpageBegin, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + }; + return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); +} +#elif defined(SQLITE_ENABLE_DBPAGE_VTAB) +int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; } +#endif /* SQLITE_ENABLE_DBSTAT_VTAB */ diff --git a/src/dbstat.c b/src/dbstat.c index c9f0fa83bf..0f1fd0a70c 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -424,7 +424,7 @@ static void statSizeAndOffset(StatCursor *pCsr){ */ fd = sqlite3PagerFile(pPager); x[0] = pCsr->iPageno; - if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ + if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ pCsr->iOffset = x[0]; pCsr->szPage = (int)x[1]; } diff --git a/src/delete.c b/src/delete.c index bf320fe7e7..746f6725b9 100644 --- a/src/delete.c +++ b/src/delete.c @@ -90,6 +90,8 @@ void sqlite3MaterializeView( Parse *pParse, /* Parsing context */ Table *pView, /* View definition */ Expr *pWhere, /* Optional WHERE clause to be added */ + ExprList *pOrderBy, /* Optional ORDER BY clause */ + Expr *pLimit, /* Optional LIMIT clause */ int iCur /* Cursor number for ephemeral table */ ){ SelectDest dest; @@ -106,8 +108,8 @@ void sqlite3MaterializeView( assert( pFrom->a[0].pOn==0 ); assert( pFrom->a[0].pUsing==0 ); } - pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, - SF_IncludeHidden, 0, 0); + pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, + SF_IncludeHidden, pLimit); sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pSel, &dest); sqlite3SelectDelete(db, pSel); @@ -129,29 +131,29 @@ Expr *sqlite3LimitWhere( Expr *pWhere, /* The WHERE clause. May be null */ ExprList *pOrderBy, /* The ORDER BY clause. May be null */ Expr *pLimit, /* The LIMIT clause. May be null */ - Expr *pOffset, /* The OFFSET clause. May be null */ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ ){ - Expr *pWhereRowid = NULL; /* WHERE rowid .. */ + sqlite3 *db = pParse->db; + Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ - Expr *pSelectRowid = NULL; /* SELECT rowid ... */ ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ Select *pSelect = NULL; /* Complete SELECT tree */ + Table *pTab; /* Check that there isn't an ORDER BY without a LIMIT clause. */ - if( pOrderBy && (pLimit == 0) ) { + if( pOrderBy && pLimit==0 ) { sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); - goto limit_where_cleanup; + sqlite3ExprDelete(pParse->db, pWhere); + sqlite3ExprListDelete(pParse->db, pOrderBy); + return 0; } /* We only need to generate a select expression if there ** is a limit/offset term to enforce. */ if( pLimit == 0 ) { - /* if pLimit is null, pOffset will always be null as well. */ - assert( pOffset == 0 ); return pWhere; } @@ -164,36 +166,47 @@ Expr *sqlite3LimitWhere( ** ); */ - pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); - if( pSelectRowid == 0 ) goto limit_where_cleanup; - pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); - if( pEList == 0 ) goto limit_where_cleanup; + pTab = pSrc->a[0].pTab; + if( HasRowid(pTab) ){ + pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); + pEList = sqlite3ExprListAppend( + pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0) + ); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + if( pPk->nKeyCol==1 ){ + const char *zName = pTab->aCol[pPk->aiColumn[0]].zName; + pLhs = sqlite3Expr(db, TK_ID, zName); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); + }else{ + int i; + for(i=0; inKeyCol; i++){ + Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName); + pEList = sqlite3ExprListAppend(pParse, pEList, p); + } + pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( pLhs ){ + pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); + } + } + } /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ + pSrc->a[0].pTab = 0; pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); - if( pSelectSrc == 0 ) { - sqlite3ExprListDelete(pParse->db, pEList); - goto limit_where_cleanup; - } + pSrc->a[0].pTab = pTab; + pSrc->a[0].pIBIndex = 0; /* generate the SELECT expression tree. */ - pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0, - pOrderBy,0,pLimit,pOffset); - if( pSelect == 0 ) return 0; + pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, + pOrderBy,0,pLimit + ); /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ - pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); - pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0; + pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); sqlite3PExprAddSelect(pParse, pInClause, pSelect); return pInClause; - -limit_where_cleanup: - sqlite3ExprDelete(pParse->db, pWhere); - sqlite3ExprListDelete(pParse->db, pOrderBy); - sqlite3ExprDelete(pParse->db, pLimit); - sqlite3ExprDelete(pParse->db, pOffset); - return 0; } #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ /* && !defined(SQLITE_OMIT_SUBQUERY) */ @@ -208,7 +221,9 @@ limit_where_cleanup: void sqlite3DeleteFrom( Parse *pParse, /* The parser context */ SrcList *pTabList, /* The table from which we should delete things */ - Expr *pWhere /* The WHERE clause. May be null */ + Expr *pWhere, /* The WHERE clause. May be null */ + ExprList *pOrderBy, /* ORDER BY clause. May be null */ + Expr *pLimit /* LIMIT clause. May be null */ ){ Vdbe *v; /* The virtual database engine */ Table *pTab; /* The table from which records will be deleted */ @@ -223,7 +238,7 @@ void sqlite3DeleteFrom( AuthContext sContext; /* Authorization context */ NameContext sNC; /* Name context to resolve expressions in */ int iDb; /* Database number */ - int memCnt = -1; /* Memory cell used for change counting */ + int memCnt = 0; /* Memory cell used for change counting */ int rcauth; /* Value returned by authorization callback */ int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ @@ -253,6 +268,7 @@ void sqlite3DeleteFrom( } assert( pTabList->nSrc==1 ); + /* Locate the table which we want to delete. This table has to be ** put in an SrcList structure because some of the subroutines we ** will be calling are designed to work with multiple tables and expect @@ -267,16 +283,26 @@ void sqlite3DeleteFrom( #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); isView = pTab->pSelect!=0; - bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); #else # define pTrigger 0 # define isView 0 #endif + bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); #ifdef SQLITE_OMIT_VIEW # undef isView # define isView 0 #endif +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( !isView ){ + pWhere = sqlite3LimitWhere( + pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE" + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + /* If pTab is really a view, make sure it has been initialized. */ if( sqlite3ViewGetColumnNames(pParse, pTab) ){ @@ -317,15 +343,19 @@ void sqlite3DeleteFrom( goto delete_from_cleanup; } if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3BeginWriteOperation(pParse, bComplex, iDb); /* If we are trying to delete from a view, realize that view into ** an ephemeral table. */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ - sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur); + sqlite3MaterializeView(pParse, pTab, + pWhere, pOrderBy, pLimit, iTabCur + ); iDataCur = iIdxCur = iTabCur; + pOrderBy = 0; + pLimit = 0; } #endif @@ -341,7 +371,10 @@ void sqlite3DeleteFrom( /* Initialize the counter of the number of rows deleted, if ** we are counting rows. */ - if( db->flags & SQLITE_CountRows ){ + if( (db->flags & SQLITE_CountRows)!=0 + && !pParse->nested + && !pParse->pTriggerTab + ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); } @@ -369,7 +402,7 @@ void sqlite3DeleteFrom( assert( !isView ); sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); if( HasRowid(pTab) ){ - sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, + sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, pTab->zName, P4_STATIC); } for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ @@ -414,9 +447,10 @@ void sqlite3DeleteFrom( eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); + if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); /* Keep track of the number of rows to be deleted */ - if( db->flags & SQLITE_CountRows ){ + if( memCnt ){ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); } @@ -429,9 +463,8 @@ void sqlite3DeleteFrom( } iKey = iPk; }else{ - iKey = pParse->nMem + 1; - iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); - if( iKey>pParse->nMem ) pParse->nMem = iKey; + iKey = ++pParse->nMem; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); } if( eOnePass!=ONEPASS_OFF ){ @@ -502,7 +535,11 @@ void sqlite3DeleteFrom( } }else if( pPk ){ addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey); + }else{ + sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); + } assert( nKey==0 ); /* OP_Found will use a composite key */ }else{ addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); @@ -515,13 +552,16 @@ void sqlite3DeleteFrom( if( IsVirtual(pTab) ){ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); - sqlite3VdbeChangeP5(v, OE_Abort); assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); sqlite3MayAbort(pParse); - if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){ - pParse->isMultiWrite = 0; + if( eOnePass==ONEPASS_SINGLE ){ + sqlite3VdbeAddOp1(v, OP_Close, iTabCur); + if( sqlite3IsToplevel(pParse) ){ + pParse->isMultiWrite = 0; + } } + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); }else #endif { @@ -555,7 +595,7 @@ void sqlite3DeleteFrom( ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ - if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ + if( memCnt ){ sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); @@ -565,6 +605,10 @@ delete_from_cleanup: sqlite3AuthContextPop(&sContext); sqlite3SrcListDelete(db, pTabList); sqlite3ExprDelete(db, pWhere); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); +#endif sqlite3DbFree(db, aToOpen); return; } @@ -722,7 +766,7 @@ void sqlite3GenerateRowDelete( u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); - if( pParse->nested==0 ){ + if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){ sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); } if( eMode!=ONEPASS_OFF ){ @@ -853,7 +897,6 @@ int sqlite3GenerateIndexKey( if( pIdx->pPartIdxWhere ){ *piPartIdxLabel = sqlite3VdbeMakeLabel(v); pParse->iSelfTab = iDataCur + 1; - sqlite3ExprCachePush(pParse); sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, SQLITE_JUMPIFNULL); pParse->iSelfTab = 0; @@ -900,6 +943,5 @@ int sqlite3GenerateIndexKey( void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ if( iLabel ){ sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); - sqlite3ExprCachePop(pParse); } } diff --git a/src/expr.c b/src/expr.c index 6a3ccd833e..b2854f9a5d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -58,8 +58,8 @@ char sqlite3ExprAffinity(Expr *pExpr){ return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif - if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){ - return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); + if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){ + return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); } if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft->flags&EP_xIsSelect ); @@ -124,6 +124,11 @@ Expr *sqlite3ExprSkipCollate(Expr *pExpr){ ** Return the collation sequence for the expression pExpr. If ** there is no defined collating sequence, return NULL. ** +** See also: sqlite3ExprNNCollSeq() +** +** The sqlite3ExprNNCollSeq() works the same exact that it returns the +** default collation if pExpr has no defined collation. +** ** The collating sequence might be determined by a COLLATE operator ** or by the presence of a column with a defined collating sequence. ** COLLATE operators take first precedence. Left operands take @@ -136,6 +141,19 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ while( p ){ int op = p->op; if( p->flags & EP_Generic ) break; + if( (op==TK_AGG_COLUMN || op==TK_COLUMN + || op==TK_REGISTER || op==TK_TRIGGER) + && p->y.pTab!=0 + ){ + /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + int j = p->iColumn; + if( j>=0 ){ + const char *zColl = p->y.pTab->aCol[j].zColl; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + } + break; + } if( op==TK_CAST || op==TK_UPLUS ){ p = p->pLeft; continue; @@ -144,19 +162,6 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } - if( (op==TK_AGG_COLUMN || op==TK_COLUMN - || op==TK_REGISTER || op==TK_TRIGGER) - && p->pTab!=0 - ){ - /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally - ** a TK_COLUMN but was previously evaluated and cached in a register */ - int j = p->iColumn; - if( j>=0 ){ - const char *zColl = p->pTab->aCol[j].zColl; - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); - } - break; - } if( p->flags & EP_Collate ){ if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ p = p->pLeft; @@ -188,6 +193,32 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ return pColl; } +/* +** Return the collation sequence for the expression pExpr. If +** there is no defined collating sequence, return a pointer to the +** defautl collation sequence. +** +** See also: sqlite3ExprCollSeq() +** +** The sqlite3ExprCollSeq() routine works the same except that it +** returns NULL if there is no defined collation. +*/ +CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){ + CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr); + if( p==0 ) p = pParse->db->pDfltColl; + assert( p!=0 ); + return p; +} + +/* +** Return TRUE if the two expressions have equivalent collating sequences. +*/ +int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){ + CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1); + CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2); + return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0; +} + /* ** pExpr is an operand of a comparison operator. aff2 is the ** type affinity of the other operand. This routine returns the @@ -550,7 +581,6 @@ static void codeVectorCompare( Expr *pL, *pR; int r1, r2; assert( i>=0 && i0 ) sqlite3ExprCachePush(pParse); r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5); @@ -562,7 +592,6 @@ static void codeVectorCompare( testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); - if( i>0 ) sqlite3ExprCachePop(pParse); if( i==nLeft-1 ){ break; } @@ -627,16 +656,15 @@ static void heightOfExprList(ExprList *p, int *pnHeight){ } } } -static void heightOfSelect(Select *p, int *pnHeight){ - if( p ){ +static void heightOfSelect(Select *pSelect, int *pnHeight){ + Select *p; + for(p=pSelect; p; p=p->pPrior){ heightOfExpr(p->pWhere, pnHeight); heightOfExpr(p->pHaving, pnHeight); heightOfExpr(p->pLimit, pnHeight); - heightOfExpr(p->pOffset, pnHeight); heightOfExprList(p->pEList, pnHeight); heightOfExprList(p->pGroupBy, pnHeight); heightOfExprList(p->pOrderBy, pnHeight); - heightOfSelect(p->pPrior, pnHeight); } } @@ -775,7 +803,7 @@ Expr *sqlite3Expr( ){ Token x; x.z = zToken; - x.n = zToken ? sqlite3Strlen30(zToken) : 0; + x.n = sqlite3Strlen30(zToken); return sqlite3ExprAlloc(db, op, &x, 0); } @@ -911,7 +939,12 @@ Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ ** Construct a new expression node for a function with multiple ** arguments. */ -Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ +Expr *sqlite3ExprFunction( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Argument list */ + Token *pToken, /* Name of the function */ + int eDistinct /* SF_Distinct or SF_ALL or 0 */ +){ Expr *pNew; sqlite3 *db = pParse->db; assert( pToken ); @@ -920,9 +953,14 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ return 0; } + if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); + } pNew->x.pList = pList; + ExprSetProperty(pNew, EP_HasFunc); assert( !ExprHasProperty(pNew, EP_xIsSelect) ); sqlite3ExprSetHeightAndFlags(pParse, pNew); + if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct); return pNew; } @@ -1014,6 +1052,10 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); /* Sanity check: Assert that the IntValue is non-negative if it exists */ assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); + + assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed ); + assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced) + || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) ); #ifdef SQLITE_DEBUG if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ assert( p->pLeft==0 ); @@ -1032,6 +1074,10 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ }else{ sqlite3ExprListDelete(db, p->x.pList); } + if( ExprHasProperty(p, EP_WinFunc) ){ + assert( p->op==TK_FUNCTION ); + sqlite3WindowDelete(db, p->y.pWin); + } } if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ @@ -1080,7 +1126,7 @@ static int exprStructSize(Expr *p){ ** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size ** (unreduced) Expr objects as they or originally constructed by the parser. ** During expression analysis, extra information is computed and moved into -** later parts of teh Expr object and that extra information might get chopped +** later parts of the Expr object and that extra information might get chopped ** off if the expression is reduced. Note also that it does not work to ** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal ** to reduce a pristine expression tree from the parser. The implementation @@ -1092,7 +1138,11 @@ static int dupedExprStructSize(Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags || p->op==TK_SELECT_COLUMN ){ + if( 0==flags || p->op==TK_SELECT_COLUMN +#ifndef SQLITE_OMIT_WINDOWFUNC + || ExprHasProperty(p, EP_WinFunc) +#endif + ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -1220,7 +1270,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ } /* Fill in pNew->pLeft and pNew->pRight. */ - if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ + if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){ zAlloc += dupedExprNodeSize(p, dupFlags); if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ pNew->pLeft = p->pLeft ? @@ -1228,6 +1278,12 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ pNew->pRight = p->pRight ? exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(p, EP_WinFunc) ){ + pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); + assert( ExprHasProperty(pNew, EP_WinFunc) ); + } +#endif /* SQLITE_OMIT_WINDOWFUNC */ if( pzBuffer ){ *pzBuffer = zAlloc; } @@ -1302,10 +1358,9 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ Expr *pPriorSelectCol = 0; assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, - sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) ); + pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p)); if( pNew==0 ) return 0; - pNew->nAlloc = pNew->nExpr = p->nExpr; + pNew->nExpr = p->nExpr; pItem = pNew->a; pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ @@ -1333,6 +1388,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pItem->sortOrder = pOldItem->sortOrder; pItem->done = 0; pItem->bSpanIsTab = pOldItem->bSpanIsTab; + pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; } return pNew; @@ -1431,7 +1487,6 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ pNew->pNext = pNext; pNew->pPrior = 0; pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); - pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); pNew->iLimit = 0; pNew->iOffset = 0; pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; @@ -1439,7 +1494,11 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); - sqlite3SelectSetName(pNew, p->zSelName); +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); +#endif + pNew->selId = p->selId; *pp = pNew; pp = &pNew->pPrior; pNext = pNew; @@ -1459,6 +1518,13 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ ** Add a new element to the end of an expression list. If pList is ** initially NULL, then create a new expression list. ** +** The pList argument must be either NULL or a pointer to an ExprList +** obtained from a prior call to sqlite3ExprListAppend(). This routine +** may not be used with an ExprList obtained from sqlite3ExprListDup(). +** Reason: This routine assumes that the number of slots in pList->a[] +** is a power of two. That is true for sqlite3ExprListAppend() returns +** but is not necessarily true from the return value of sqlite3ExprListDup(). +** ** If a memory allocation error occurs, the entire list is freed and ** NULL is returned. If non-NULL is returned, then it is guaranteed ** that the new entry was successfully appended. @@ -1477,16 +1543,14 @@ ExprList *sqlite3ExprListAppend( goto no_mem; } pList->nExpr = 0; - pList->nAlloc = 1; - }else if( pList->nExpr==pList->nAlloc ){ + }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ ExprList *pNew; pNew = sqlite3DbRealloc(db, pList, - sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0])); + sizeof(*pList)+(2*pList->nExpr - 1)*sizeof(pList->a[0])); if( pNew==0 ){ goto no_mem; } pList = pNew; - pList->nAlloc *= 2; } pItem = &pList->a[pList->nExpr++]; assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) ); @@ -1606,6 +1670,9 @@ void sqlite3ExprListSetName( assert( pItem->zName==0 ); pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); if( dequote ) sqlite3Dequote(pItem->zName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName); + } } } @@ -1620,17 +1687,16 @@ void sqlite3ExprListSetName( void sqlite3ExprListSetSpan( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to add the span. */ - ExprSpan *pSpan /* The span to be added */ + const char *zStart, /* Start of the span */ + const char *zEnd /* End of the span */ ){ sqlite3 *db = pParse->db; assert( pList!=0 || db->mallocFailed!=0 ); if( pList ){ struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; assert( pList->nExpr>0 ); - assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr ); sqlite3DbFree(db, pItem->zSpan); - pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart, - (int)(pSpan->zEnd - pSpan->zStart)); + pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd); } } @@ -1677,16 +1743,56 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ u32 sqlite3ExprListFlags(const ExprList *pList){ int i; u32 m = 0; - if( pList ){ - for(i=0; inExpr; i++){ - Expr *pExpr = pList->a[i].pExpr; - assert( pExpr!=0 ); - m |= pExpr->flags; - } + assert( pList!=0 ); + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + assert( pExpr!=0 ); + m |= pExpr->flags; } return m; } +/* +** This is a SELECT-node callback for the expression walker that +** always "fails". By "fail" in this case, we mean set +** pWalker->eCode to zero and abort. +** +** This callback is used by multiple expression walkers. +*/ +int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ + UNUSED_PARAMETER(NotUsed); + pWalker->eCode = 0; + return WRC_Abort; +} + +/* +** If the input expression is an ID with the name "true" or "false" +** then convert it into an TK_TRUEFALSE term. Return non-zero if +** the conversion happened, and zero if the expression is unaltered. +*/ +int sqlite3ExprIdToTrueFalse(Expr *pExpr){ + assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); + if( sqlite3StrICmp(pExpr->u.zToken, "true")==0 + || sqlite3StrICmp(pExpr->u.zToken, "false")==0 + ){ + pExpr->op = TK_TRUEFALSE; + return 1; + } + return 0; +} + +/* +** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE +** and 0 if it is FALSE. +*/ +int sqlite3ExprTruthValue(const Expr *pExpr){ + assert( pExpr->op==TK_TRUEFALSE ); + assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 + || sqlite3StrICmp(pExpr->u.zToken,"false")==0 ); + return pExpr->u.zToken[4]==0; +} + + /* ** These routines are Walker callbacks used to check expressions to ** see if they are "constant" for some definition of constant. The @@ -1734,6 +1840,12 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ return WRC_Abort; } case TK_ID: + /* Convert "true" or "false" in a DEFAULT clause into the + ** appropriate TK_TRUEFALSE operator */ + if( sqlite3ExprIdToTrueFalse(pExpr) ){ + return WRC_Prune; + } + /* Fall thru */ case TK_COLUMN: case TK_AGG_FUNCTION: case TK_AGG_COLUMN: @@ -1741,11 +1853,16 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); testcase( pExpr->op==TK_AGG_COLUMN ); + if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){ + return WRC_Continue; + } if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ return WRC_Continue; } /* Fall through */ case TK_IF_NULL_ROW: + case TK_REGISTER: + testcase( pExpr->op==TK_REGISTER ); testcase( pExpr->op==TK_IF_NULL_ROW ); pWalker->eCode = 0; return WRC_Abort; @@ -1763,21 +1880,16 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ } /* Fall through */ default: - testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */ - testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */ + testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */ + testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */ return WRC_Continue; } } -static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){ - UNUSED_PARAMETER(NotUsed); - pWalker->eCode = 0; - return WRC_Abort; -} static int exprIsConst(Expr *p, int initFlag, int iCur){ Walker w; w.eCode = initFlag; w.xExprCallback = exprNodeIsConstant; - w.xSelectCallback = selectNodeIsConstant; + w.xSelectCallback = sqlite3SelectWalkFail; #ifdef SQLITE_DEBUG w.xSelectCallback2 = sqlite3SelectWalkAssert2; #endif @@ -1799,10 +1911,17 @@ int sqlite3ExprIsConstant(Expr *p){ } /* -** Walk an expression tree. Return non-zero if the expression is constant -** that does no originate from the ON or USING clauses of a join. -** Return 0 if it involves variables or function calls or terms from -** an ON or USING clause. +** Walk an expression tree. Return non-zero if +** +** (1) the expression is constant, and +** (2) the expression does originate in the ON or USING clause +** of a LEFT JOIN, and +** (3) the expression does not contain any EP_FixedCol TK_COLUMN +** operands created by the constant propagation optimization. +** +** When this routine returns true, it indicates that the expression +** can be added to the pParse->pConstExpr list and evaluated once when +** the prepared statement starts up. See sqlite3ExprCodeAtInit(). */ int sqlite3ExprIsConstantNotJoin(Expr *p){ return exprIsConst(p, 2, 0); @@ -1831,8 +1950,8 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ for(i=0; inExpr; i++){ Expr *p = pGroupBy->a[i].pExpr; if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){ - CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p); - if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p); + if( sqlite3IsBinary(pColl) ){ return WRC_Prune; } } @@ -1900,7 +2019,7 @@ int sqlite3ExprContainsSubquery(Expr *p){ Walker w; w.eCode = 1; w.xExprCallback = sqlite3ExprWalkNoop; - w.xSelectCallback = selectNodeIsConstant; + w.xSelectCallback = sqlite3SelectWalkFail; #ifdef SQLITE_DEBUG w.xSelectCallback2 = sqlite3SelectWalkAssert2; #endif @@ -1973,9 +2092,9 @@ int sqlite3ExprCanBeNull(const Expr *p){ case TK_BLOB: return 0; case TK_COLUMN: - assert( p->pTab!=0 ); return ExprHasProperty(p, EP_CanBeNull) || - (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); + p->y.pTab==0 || /* Reference to column of index on expression */ + (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; } @@ -2056,7 +2175,6 @@ static Select *isCandidateForInOpt(Expr *pX){ } assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ if( p->pLimit ) return 0; /* Has no LIMIT clause */ - assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */ if( p->pWhere ) return 0; /* Has no WHERE clause */ pSrc = p->pSrc; assert( pSrc!=0 ); @@ -2146,16 +2264,15 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** pX->iTable made to point to the ephemeral table instead of an ** existing table. ** -** The inFlags parameter must contain exactly one of the bits -** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains -** IN_INDEX_MEMBERSHIP, then the generated table will be used for a -** fast membership test. When the IN_INDEX_LOOP bit is set, the -** IN index will be used to loop over all values of the RHS of the -** IN operator. +** The inFlags parameter must contain, at a minimum, one of the bits +** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains +** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast +** membership test. When the IN_INDEX_LOOP bit is set, the IN index will +** be used to loop over all values of the RHS of the IN operator. ** ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate ** through the set members) then the b-tree must not contain duplicates. -** An epheremal table must be used unless the selected columns are guaranteed +** An epheremal table will be created unless the selected columns are guaranteed ** to be unique - either because it is an INTEGER PRIMARY KEY or due to ** a UNIQUE constraint or index. ** @@ -2256,7 +2373,8 @@ int sqlite3FindInIndex( sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; - + ExplainQueryPlan((pParse, 0, + "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName)); sqlite3VdbeJumpHere(v, iAddr); }else{ Index *pIdx; /* Iterator variable */ @@ -2335,11 +2453,8 @@ int sqlite3FindInIndex( if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); -#ifndef SQLITE_OMIT_EXPLAIN - sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, - sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName), - P4_DYNAMIC); -#endif + ExplainQueryPlan((pParse, 0, + "USING INDEX %s FOR IN-OPERATOR",pIdx->zName)); sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); @@ -2518,7 +2633,6 @@ int sqlite3CodeSubselect( int rReg = 0; /* Register storing resulting */ Vdbe *v = sqlite3GetVdbe(pParse); if( NEVER(v==0) ) return 0; - sqlite3ExprCachePush(pParse); /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: @@ -2534,17 +2648,6 @@ int sqlite3CodeSubselect( jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } -#ifndef SQLITE_OMIT_EXPLAIN - if( pParse->explain==2 ){ - char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d", - jmpIfDynamic>=0?"":"CORRELATED ", - pExpr->op==TK_IN?"LIST":"SCALAR", - pParse->iNextSelectId - ); - sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); - } -#endif - switch( pExpr->op ){ case TK_IN: { int addr; /* Address of OP_OpenEphemeral instruction */ @@ -2582,6 +2685,9 @@ int sqlite3CodeSubselect( Select *pSelect = pExpr->x.pSelect; ExprList *pEList = pSelect->pEList; + ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY", + jmpIfDynamic>=0?"":"CORRELATED " + )); assert( !isRowid ); /* If the LHS and RHS of the IN operator do not match, that ** error will have been caught long before we reach this point. */ @@ -2623,7 +2729,6 @@ int sqlite3CodeSubselect( ExprList *pList = pExpr->x.pList; struct ExprList_item *pItem; int r1, r2, r3; - affinity = sqlite3ExprAffinity(pLeft); if( !affinity ){ affinity = SQLITE_AFF_BLOB; @@ -2636,7 +2741,7 @@ int sqlite3CodeSubselect( /* Loop through each expression in . */ r1 = sqlite3GetTempReg(pParse); r2 = sqlite3GetTempReg(pParse); - if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2); + if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC); for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ Expr *pE2 = pItem->pExpr; int iValToIns; @@ -2663,7 +2768,6 @@ int sqlite3CodeSubselect( sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); - sqlite3ExprCacheAffinityChange(pParse, r3, 1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1); } } @@ -2696,6 +2800,7 @@ int sqlite3CodeSubselect( Select *pSel; /* SELECT statement to encode */ SelectDest dest; /* How to deal with SELECT result */ int nReg; /* Registers to allocate */ + Expr *pLimit; /* New limit expression */ testcase( pExpr->op==TK_EXISTS ); testcase( pExpr->op==TK_SELECT ); @@ -2703,6 +2808,8 @@ int sqlite3CodeSubselect( assert( ExprHasProperty(pExpr, EP_xIsSelect) ); pSel = pExpr->x.pSelect; + ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY", + jmpIfDynamic>=0?"":"CORRELATED ")); nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); pParse->nMem += nReg; @@ -2717,11 +2824,14 @@ int sqlite3CodeSubselect( sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); VdbeComment((v, "Init EXISTS result")); } - sqlite3ExprDelete(pParse->db, pSel->pLimit); - pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER, - &sqlite3IntTokens[1], 0); + pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0); + if( pSel->pLimit ){ + sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft); + pSel->pLimit->pLeft = pLimit; + }else{ + pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); + } pSel->iLimit = 0; - pSel->selFlags &= ~SF_MultiValue; if( sqlite3Select(pParse, pSel, &dest) ){ return 0; } @@ -2738,7 +2848,6 @@ int sqlite3CodeSubselect( if( jmpIfDynamic>=0 ){ sqlite3VdbeJumpHere(v, jmpIfDynamic); } - sqlite3ExprCachePop(pParse); return rReg; } @@ -2857,7 +2966,6 @@ static void sqlite3ExprCodeIN( ** aiMap[] array contains a mapping from the original LHS field order to ** the field order that matches the RHS index. */ - sqlite3ExprCachePush(pParse); rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy); for(i=0; idb, aiMap); @@ -3064,7 +3171,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ const char *z = pExpr->u.zToken; assert( z!=0 ); c = sqlite3DecOrHexToI64(z, &value); - if( c==1 || (c==2 && !negFlag) || (negFlag && value==SMALLEST_INT64)){ + if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){ #ifdef SQLITE_OMIT_FLOATING_POINT sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); #else @@ -3078,151 +3185,12 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ } #endif }else{ - if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } + if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; } sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); } } } -/* -** Erase column-cache entry number i -*/ -static void cacheEntryClear(Parse *pParse, int i){ - if( pParse->aColCache[i].tempReg ){ - if( pParse->nTempRegaTempReg) ){ - pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; - } - } - pParse->nColCache--; - if( inColCache ){ - pParse->aColCache[i] = pParse->aColCache[pParse->nColCache]; - } -} - - -/* -** Record in the column cache that a particular column from a -** particular table is stored in a particular register. -*/ -void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ - int i; - int minLru; - int idxLru; - struct yColCache *p; - - /* Unless an error has occurred, register numbers are always positive. */ - assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed ); - assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ - - /* The SQLITE_ColumnCache flag disables the column cache. This is used - ** for testing only - to verify that SQLite always gets the same answer - ** with and without the column cache. - */ - if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return; - - /* First replace any existing entry. - ** - ** Actually, the way the column cache is currently used, we are guaranteed - ** that the object will never already be in cache. Verify this guarantee. - */ -#ifndef NDEBUG - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - assert( p->iTable!=iTab || p->iColumn!=iCol ); - } -#endif - - /* If the cache is already full, delete the least recently used entry */ - if( pParse->nColCache>=SQLITE_N_COLCACHE ){ - minLru = 0x7fffffff; - idxLru = -1; - for(i=0, p=pParse->aColCache; ilrulru; - } - } - p = &pParse->aColCache[idxLru]; - }else{ - p = &pParse->aColCache[pParse->nColCache++]; - } - - /* Add the new entry to the end of the cache */ - p->iLevel = pParse->iCacheLevel; - p->iTable = iTab; - p->iColumn = iCol; - p->iReg = iReg; - p->tempReg = 0; - p->lru = pParse->iCacheCnt++; -} - -/* -** Indicate that registers between iReg..iReg+nReg-1 are being overwritten. -** Purge the range of registers from the column cache. -*/ -void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ - int i = 0; - while( inColCache ){ - struct yColCache *p = &pParse->aColCache[i]; - if( p->iReg >= iReg && p->iReg < iReg+nReg ){ - cacheEntryClear(pParse, i); - }else{ - i++; - } - } -} - -/* -** Remember the current column cache context. Any new entries added -** added to the column cache after this call are removed when the -** corresponding pop occurs. -*/ -void sqlite3ExprCachePush(Parse *pParse){ - pParse->iCacheLevel++; -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("PUSH to %d\n", pParse->iCacheLevel); - } -#endif -} - -/* -** Remove from the column cache any entries that were added since the -** the previous sqlite3ExprCachePush operation. In other words, restore -** the cache to the state it was in prior the most recent Push. -*/ -void sqlite3ExprCachePop(Parse *pParse){ - int i = 0; - assert( pParse->iCacheLevel>=1 ); - pParse->iCacheLevel--; -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("POP to %d\n", pParse->iCacheLevel); - } -#endif - while( inColCache ){ - if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){ - cacheEntryClear(pParse, i); - }else{ - i++; - } - } -} - -/* -** When a cached column is reused, make sure that its register is -** no longer available as a temp register. ticket #3879: that same -** register might be in the cache in multiple places, so be sure to -** get them all. -*/ -static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iReg==iReg ){ - p->tempReg = 0; - } - } -} /* Generate code that will load into register regOut a value that is ** appropriate for the iIdxCol-th column of index pIdx. @@ -3278,12 +3246,7 @@ void sqlite3ExprCodeGetColumnOfTable( /* ** Generate code that will extract the iColumn-th column from -** table pTab and store the column value in a register. -** -** An effort is made to store the column value in register iReg. This -** is not garanteeed for GetColumn() - the result can be stored in -** any register. But the result is guaranteed to land in register iReg -** for GetColumnToReg(). +** table pTab and store the column value in register iReg. ** ** There must be an open cursor to pTab in iTable when this routine ** is called. If iColumn<0 then code is generated that extracts the rowid. @@ -3297,96 +3260,23 @@ int sqlite3ExprCodeGetColumn( u8 p5 /* P5 value for OP_Column + FLAGS */ ){ Vdbe *v = pParse->pVdbe; - int i; - struct yColCache *p; - - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iTable==iTable && p->iColumn==iColumn ){ - p->lru = pParse->iCacheCnt++; - sqlite3ExprCachePinRegister(pParse, p->iReg); - return p->iReg; - } - } assert( v!=0 ); sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); if( p5 ){ sqlite3VdbeChangeP5(v, p5); - }else{ - sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); } return iReg; } -void sqlite3ExprCodeGetColumnToReg( - Parse *pParse, /* Parsing and code generating context */ - Table *pTab, /* Description of the table we are reading from */ - int iColumn, /* Index of the table column */ - int iTable, /* The cursor pointing to the table */ - int iReg /* Store results here */ -){ - int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0); - if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg); -} - - -/* -** Clear all column cache entries. -*/ -void sqlite3ExprCacheClear(Parse *pParse){ - int i; - -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("CLEAR\n"); - } -#endif - for(i=0; inColCache; i++){ - if( pParse->aColCache[i].tempReg - && pParse->nTempRegaTempReg) - ){ - pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; - } - } - pParse->nColCache = 0; -} - -/* -** Record the fact that an affinity change has occurred on iCount -** registers starting with iStart. -*/ -void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ - sqlite3ExprCacheRemove(pParse, iStart, iCount); -} /* ** Generate code to move content from registers iFrom...iFrom+nReg-1 -** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. +** over to iTo..iTo+nReg-1. */ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); - sqlite3ExprCacheRemove(pParse, iFrom, nReg); } -#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) -/* -** Return true if any register in the range iFrom..iTo (inclusive) -** is used as part of the column cache. -** -** This routine is used within assert() and testcase() macros only -** and does not appear in a normal build. -*/ -static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - int r = p->iReg; - if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ - } - return 0; -} -#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ - - /* ** Convert a scalar expression node to a TK_REGISTER referencing ** register iReg. The caller must ensure that iReg already contains @@ -3462,6 +3352,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ return 0; } +expr_code_doover: if( pExpr==0 ){ op = TK_NULL; }else{ @@ -3483,6 +3374,28 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } case TK_COLUMN: { int iTab = pExpr->iTable; + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + /* This COLUMN expression is really a constant due to WHERE clause + ** constraints, and that constant is coded by the pExpr->pLeft + ** expresssion. However, make sure the constant has the correct + ** datatype by applying the Affinity of the table column to the + ** constant. + */ + int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + if( aff!=SQLITE_AFF_BLOB ){ + static const char zAff[] = "B\000C\000D\000E"; + assert( SQLITE_AFF_BLOB=='A' ); + assert( SQLITE_AFF_TEXT=='B' ); + if( iReg!=target ){ + sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target); + iReg = target; + } + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, + &zAff[(aff-'B')*2], P4_STATIC); + } + return iReg; + } if( iTab<0 ){ if( pParse->iSelfTab<0 ){ /* Generating CHECK constraints or inserting into partial index */ @@ -3493,7 +3406,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ iTab = pParse->iSelfTab - 1; } } - return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); } @@ -3501,6 +3414,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ codeInteger(pParse, pExpr, 0, target); return target; } + case TK_TRUEFALSE: { + sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target); + return target; + } #ifndef SQLITE_OMIT_FLOATING_POINT case TK_FLOAT: { assert( !ExprHasProperty(pExpr, EP_IntValue) ); @@ -3559,8 +3476,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } sqlite3VdbeAddOp2(v, OP_Cast, target, sqlite3AffinityType(pExpr->u.zToken, 0)); - testcase( usedAsColumnCache(pParse, inReg, inReg) ); - sqlite3ExprCacheAffinityChange(pParse, inReg, 1); return inReg; } #endif /* SQLITE_OMIT_CAST */ @@ -3656,6 +3571,18 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp2(v, op, r1, inReg); break; } + case TK_TRUTH: { + int isTrue; /* IS TRUE or IS NOT TRUE */ + int bNormal; /* IS TRUE or IS FALSE */ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + bNormal = pExpr->op2==TK_IS; + testcase( isTrue && bNormal); + testcase( !isTrue && bNormal); + sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal); + break; + } case TK_ISNULL: case TK_NOTNULL: { int addr; @@ -3692,6 +3619,12 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + return pExpr->y.pWin->regResult; + } +#endif + if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ /* SQL functions can be expensive. So try to move constant functions ** out of the inner loop, even if that means an extra OP_Copy. */ @@ -3728,10 +3661,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ for(i=1; ia[i].pExpr, target); - sqlite3ExprCachePop(pParse); } sqlite3VdbeResolveLabel(v, endCoalesce); break; @@ -3797,10 +3727,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } } - sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); - sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ }else{ r1 = 0; } @@ -3817,7 +3745,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ ** "glob(B,A). We want to use the A in "A glob B" to test ** for function overloading. But we use the B term in "glob(B,A)". */ - if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ + if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); }else if( nFarg>0 ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); @@ -3827,9 +3755,21 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( !pColl ) pColl = db->pDfltColl; sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); } - sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0, - constMask, r1, target, (char*)pDef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nFarg); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){ + Expr *pArg = pFarg->a[0].pExpr; + if( pArg->op==TK_COLUMN ){ + sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + }else +#endif + { + sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0, + constMask, r1, target, (char*)pDef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nFarg); + } if( nFarg && constMask==0 ){ sqlite3ReleaseTempRange(pParse, r1, nFarg); } @@ -3894,7 +3834,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_SPAN: case TK_COLLATE: case TK_UPLUS: { - return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + pExpr = pExpr->pLeft; + goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */ } case TK_TRIGGER: { @@ -3923,7 +3864,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ ** p1==1 -> old.a p1==4 -> new.a ** p1==2 -> old.b p1==5 -> new.b */ - Table *pTab = pExpr->pTab; + Table *pTab = pExpr->y.pTab; int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; assert( pExpr->iTable==0 || pExpr->iTable==1 ); @@ -3932,10 +3873,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( p1>=0 && p1<(pTab->nCol*2+2) ); sqlite3VdbeAddOp2(v, OP_Param, p1, target); - VdbeComment((v, "%s.%s -> $%d", + VdbeComment((v, "r[%d]=%s.%s", target, (pExpr->iTable ? "new" : "old"), - (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName), - target + (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName) )); #ifndef SQLITE_OMIT_FLOATING_POINT @@ -3961,9 +3901,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_IF_NULL_ROW: { int addrINR; addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); - sqlite3ExprCachePush(pParse); inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); - sqlite3ExprCachePop(pParse); sqlite3VdbeJumpHere(v, addrINR); sqlite3VdbeChangeP3(v, addrINR, inReg); break; @@ -4000,7 +3938,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ Expr opCompare; /* The X==Ei expression */ Expr *pX; /* The X expression */ Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ - VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); assert(pExpr->x.pList->nExpr > 0); @@ -4024,7 +3961,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ regFree1 = 0; } for(i=0; iop==TK_COLUMN ); sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeGoto(v, endLabel); - sqlite3ExprCachePop(pParse); sqlite3VdbeResolveLabel(v, nextCase); } if( (nExpr&1)!=0 ){ - sqlite3ExprCachePush(pParse); sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); - sqlite3ExprCachePop(pParse); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } - assert( pParse->db->mallocFailed || pParse->nErr>0 - || pParse->iCacheLevel==iCacheLevel ); sqlite3VdbeResolveLabel(v, endLabel); break; } @@ -4198,7 +4129,7 @@ void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ ** might choose to code the expression at initialization time. */ void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ - if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ sqlite3ExprCodeAtInit(pParse, pExpr, target); }else{ sqlite3ExprCode(pParse, pExpr, target); @@ -4233,7 +4164,9 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ ** Generate code that pushes the value of every element of the given ** expression list into a sequence of registers beginning at target. ** -** Return the number of elements evaluated. +** Return the number of elements evaluated. The number returned will +** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF +** is defined. ** ** The SQLITE_ECEL_DUP flag prevents the arguments from being ** filled using OP_SCopy. OP_Copy must be used instead. @@ -4244,6 +4177,8 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ ** The SQLITE_ECEL_REF flag means that expressions in the list with ** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored ** in registers at srcReg, and so the value can be copied from there. +** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0 +** are simply omitted rather than being copied from srcReg. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ @@ -4263,6 +4198,12 @@ int sqlite3ExprCodeExprList( if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; for(pItem=pList->a, i=0; ipExpr; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( pItem->bSorterRef ){ + i--; + n--; + }else +#endif if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){ if( flags & SQLITE_ECEL_OMITREF ){ i--; @@ -4270,7 +4211,9 @@ int sqlite3ExprCodeExprList( }else{ sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } - }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ + }else if( (flags & SQLITE_ECEL_FACTOR)!=0 + && sqlite3ExprIsConstantNotJoin(pExpr) + ){ sqlite3ExprCodeAtInit(pParse, pExpr, target+i); }else{ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); @@ -4396,18 +4339,14 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse); break; } case TK_OR: { testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse); break; } case TK_NOT: { @@ -4415,6 +4354,23 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); break; } + case TK_TRUTH: { + int isNot; /* IS NOT TRUE or IS NOT FALSE */ + int isTrue; /* IS TRUE or IS NOT TRUE */ + testcase( jumpIfNull==0 ); + isNot = pExpr->op2==TK_ISNOT; + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + testcase( isTrue && isNot ); + testcase( !isTrue && isNot ); + if( isTrue ^ isNot ){ + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + }else{ + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + } + break; + } case TK_IS: case TK_ISNOT: testcase( op==TK_IS ); @@ -4549,19 +4505,15 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_AND: { testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse); break; } case TK_OR: { int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse); break; } case TK_NOT: { @@ -4569,6 +4521,26 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); break; } + case TK_TRUTH: { + int isNot; /* IS NOT TRUE or IS NOT FALSE */ + int isTrue; /* IS TRUE or IS NOT TRUE */ + testcase( jumpIfNull==0 ); + isNot = pExpr->op2==TK_ISNOT; + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + testcase( isTrue && isNot ); + testcase( !isTrue && isNot ); + if( isTrue ^ isNot ){ + /* IS TRUE and IS NOT FALSE */ + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + isNot ? 0 : SQLITE_JUMPIFNULL); + + }else{ + /* IS FALSE and IS NOT TRUE */ + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + isNot ? 0 : SQLITE_JUMPIFNULL); + } + break; + } case TK_IS: case TK_ISNOT: testcase( pExpr->op==TK_IS ); @@ -4754,17 +4726,35 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){ if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ if( pA->op==TK_FUNCTION ){ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; +#ifndef SQLITE_OMIT_WINDOWFUNC + /* Justification for the assert(): + ** window functions have p->op==TK_FUNCTION but aggregate functions + ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate + ** function and a window function should have failed before reaching + ** this point. And, it is not possible to have a window function and + ** a scalar function with the same name and number of arguments. So + ** if we reach this point, either A and B both window functions or + ** neither are a window functions. */ + assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) ); + if( ExprHasProperty(pA,EP_WinFunc) ){ + if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2; + } +#endif + }else if( pA->op==TK_COLLATE ){ + if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ - return pA->op==TK_COLLATE ? 1 : 2; + return 2; } } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ if( combinedFlags & EP_xIsSelect ) return 2; - if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; + if( (combinedFlags & EP_FixedCol)==0 + && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; - if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){ + assert( (combinedFlags & EP_Reduced)==0 ); + if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; @@ -4856,6 +4846,102 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ return 0; } +/* +** This is the Expr node callback for sqlite3ExprImpliesNotNullRow(). +** If the expression node requires that the table at pWalker->iCur +** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. +** +** This routine controls an optimization. False positives (setting +** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives +** (never setting pWalker->eCode) is a harmless missed optimization. +*/ +static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune; + switch( pExpr->op ){ + case TK_ISNOT: + case TK_NOT: + case TK_ISNULL: + case TK_IS: + case TK_OR: + case TK_CASE: + case TK_IN: + case TK_FUNCTION: + testcase( pExpr->op==TK_ISNOT ); + testcase( pExpr->op==TK_NOT ); + testcase( pExpr->op==TK_ISNULL ); + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_OR ); + testcase( pExpr->op==TK_CASE ); + testcase( pExpr->op==TK_IN ); + testcase( pExpr->op==TK_FUNCTION ); + return WRC_Prune; + case TK_COLUMN: + if( pWalker->u.iCur==pExpr->iTable ){ + pWalker->eCode = 1; + return WRC_Abort; + } + return WRC_Prune; + + /* Virtual tables are allowed to use constraints like x=NULL. So + ** a term of the form x=y does not prove that y is not null if x + ** is the column of a virtual table */ + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); + if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) + || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) + ){ + return WRC_Prune; + } + default: + return WRC_Continue; + } +} + +/* +** Return true (non-zero) if expression p can only be true if at least +** one column of table iTab is non-null. In other words, return true +** if expression p will always be NULL or false if every column of iTab +** is NULL. +** +** False negatives are acceptable. In other words, it is ok to return +** zero even if expression p will never be true of every column of iTab +** is NULL. A false negative is merely a missed optimization opportunity. +** +** False positives are not allowed, however. A false positive may result +** in an incorrect answer. +** +** Terms of p that are marked with EP_FromJoin (and hence that come from +** the ON or USING clauses of LEFT JOINS) are excluded from the analysis. +** +** This routine is used to check if a LEFT JOIN can be converted into +** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE +** clause requires that some column of the right table of the LEFT JOIN +** be non-NULL, then the LEFT JOIN can be safely converted into an +** ordinary join. +*/ +int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ + Walker w; + w.xExprCallback = impliesNotNullRow; + w.xSelectCallback = 0; + w.xSelectCallback2 = 0; + w.eCode = 0; + w.u.iCur = iTab; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + /* ** An instance of the following structure is used by the tree walker ** to determine if an expression can be evaluated by reference to the @@ -5011,8 +5097,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ NameContext *pNC = pWalker->u.pNC; Parse *pParse = pNC->pParse; SrcList *pSrcList = pNC->pSrcList; - AggInfo *pAggInfo = pNC->pAggInfo; + AggInfo *pAggInfo = pNC->uNC.pAggInfo; + assert( pNC->ncFlags & NC_UAggInfo ); switch( pExpr->op ){ case TK_AGG_COLUMN: case TK_COLUMN: { @@ -5044,7 +5131,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 ){ pCol = &pAggInfo->aCol[k]; - pCol->pTab = pExpr->pTab; + pCol->pTab = pExpr->y.pTab; pCol->iTable = pExpr->iTable; pCol->iColumn = pExpr->iColumn; pCol->iMem = ++pParse->nMem; @@ -5190,21 +5277,9 @@ int sqlite3GetTempReg(Parse *pParse){ /* ** Deallocate a register, making available for reuse for some other ** purpose. -** -** If a register is currently being used by the column cache, then -** the deallocation is deferred until the column cache line that uses -** the register becomes stale. */ void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ if( iReg && pParse->nTempRegaTempReg) ){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iReg==iReg ){ - p->tempReg = 1; - return; - } - } pParse->aTempReg[pParse->nTempReg++] = iReg; } } @@ -5218,7 +5293,6 @@ int sqlite3GetTempRange(Parse *pParse, int nReg){ i = pParse->iRangeReg; n = pParse->nRangeReg; if( nReg<=n ){ - assert( !usedAsColumnCache(pParse, i, i+n-1) ); pParse->iRangeReg += nReg; pParse->nRangeReg -= nReg; }else{ @@ -5232,7 +5306,6 @@ void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ sqlite3ReleaseTempReg(pParse, iReg); return; } - sqlite3ExprCacheRemove(pParse, iReg, nReg); if( nReg>pParse->nRangeReg ){ pParse->nRangeReg = nReg; pParse->iRangeReg = iReg; diff --git a/src/fkey.c b/src/fkey.c index 0012768a39..6777d71eaf 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -331,6 +331,12 @@ static void fkLookupParent( int iCur = pParse->nTab - 1; /* Cursor number to use */ int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */ + sqlite3VdbeVerifyAbortable(v, + (!pFKey->isDeferred + && !(pParse->db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel + && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore); + /* If nIncr is less than zero, then check at runtime if there are any ** outstanding constraints to resolve. If there are not, there is no need ** to check if deleting this row resolves any outstanding violations. @@ -496,7 +502,7 @@ static Expr *exprTableColumn( ){ Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); if( pExpr ){ - pExpr->pTab = pTab; + pExpr->y.pTab = pTab; pExpr->iTable = iCursor; pExpr->iColumn = iCol; } @@ -704,11 +710,12 @@ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ */ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ sqlite3 *db = pParse->db; - if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){ + if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){ int iSkip = 0; Vdbe *v = sqlite3GetVdbe(pParse); assert( v ); /* VDBE has already been allocated */ + assert( pTab->pSelect==0 ); /* Not a view */ if( sqlite3FkReferences(pTab)==0 ){ /* Search for a deferred foreign key constraint for which this table ** is the child table. If one cannot be found, return without @@ -725,7 +732,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ } pParse->disableTriggers = 1; - sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0); pParse->disableTriggers = 0; /* If the DELETE has generated immediate foreign key constraint @@ -738,6 +745,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ ** constraints are violated. */ if( (db->flags & SQLITE_DeferFKs)==0 ){ + sqlite3VdbeVerifyAbortable(v, OE_Abort); sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, @@ -1283,7 +1291,7 @@ static Trigger *fkActionTrigger( sqlite3ExprListAppend(pParse, 0, pRaise), sqlite3SrcListAppend(db, 0, &tFrom, 0), pWhere, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 ); pWhere = 0; } diff --git a/src/func.c b/src/func.c index 2bb9a91de6..0504a8f026 100644 --- a/src/func.c +++ b/src/func.c @@ -35,6 +35,8 @@ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ ** iteration of the aggregate loop. */ static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ + assert( context->isError<=0 ); + context->isError = -1; context->skipFlag = 1; } @@ -101,8 +103,6 @@ static void lengthFunc( int argc, sqlite3_value **argv ){ - int len; - assert( argc==1 ); UNUSED_PARAMETER(argc); switch( sqlite3_value_type(argv[0]) ){ @@ -114,13 +114,17 @@ static void lengthFunc( } case SQLITE_TEXT: { const unsigned char *z = sqlite3_value_text(argv[0]); + const unsigned char *z0; + unsigned char c; if( z==0 ) return; - len = 0; - while( *z ){ - len++; - SQLITE_SKIP_UTF8(z); + z0 = z; + while( (c = *z)!=0 ){ + z++; + if( c>=0xc0 ){ + while( (*z & 0xc0)==0x80 ){ z++; z0++; } + } } - sqlite3_result_int(context, len); + sqlite3_result_int(context, (int)(z-z0)); break; } default: { @@ -247,7 +251,7 @@ static void printfFunc( x.apArg = argv+1; sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); str.printfFlags = SQLITE_PRINTF_SQLFUNC; - sqlite3XPrintf(&str, zFormat, &x); + sqlite3_str_appendf(&str, zFormat, &x); n = str.nChar; sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, SQLITE_DYNAMIC); @@ -698,16 +702,20 @@ static int patternCompare( ** c or cx. */ if( c<=0x80 ){ - u32 cx; + char zStop[3]; int bMatch; if( noCase ){ - cx = sqlite3Toupper(c); - c = sqlite3Tolower(c); + zStop[0] = sqlite3Toupper(c); + zStop[1] = sqlite3Tolower(c); + zStop[2] = 0; }else{ - cx = c; + zStop[0] = c; + zStop[1] = 0; } - while( (c2 = *(zString++))!=0 ){ - if( c2!=c && c2!=cx ) continue; + while(1){ + zString += strcspn((const char*)zString, zStop); + if( zString[0]==0 ) break; + zString++; bMatch = patternCompare(zPattern,zString,pInfo,matchOther); if( bMatch!=SQLITE_NOMATCH ) return bMatch; } @@ -865,7 +873,8 @@ static void likeFunc( #ifdef SQLITE_TEST sqlite3_like_count++; #endif - sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); + sqlite3_result_int(context, + patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); } } @@ -1190,6 +1199,8 @@ static void replaceFunc( i64 nOut; /* Maximum size of zOut */ int loopLimit; /* Last zStr[] that might match zPattern[] */ int i, j; /* Loop counters */ + unsigned cntExpand; /* Number zOut expansions */ + sqlite3 *db = sqlite3_context_db_handle(context); assert( argc==3 ); UNUSED_PARAMETER(argc); @@ -1221,33 +1232,40 @@ static void replaceFunc( return; } loopLimit = nStr - nPattern; + cntExpand = 0; for(i=j=0; i<=loopLimit; i++){ if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){ zOut[j++] = zStr[i]; }else{ - u8 *zOld; - sqlite3 *db = sqlite3_context_db_handle(context); - nOut += nRep - nPattern; - testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] ); - testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); - if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - sqlite3_result_error_toobig(context); - sqlite3_free(zOut); - return; - } - zOld = zOut; - zOut = sqlite3_realloc64(zOut, (int)nOut); - if( zOut==0 ){ - sqlite3_result_error_nomem(context); - sqlite3_free(zOld); - return; + if( nRep>nPattern ){ + nOut += nRep - nPattern; + testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); + if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + sqlite3_free(zOut); + return; + } + cntExpand++; + if( (cntExpand&(cntExpand-1))==0 ){ + /* Grow the size of the output buffer only on substitutions + ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */ + u8 *zOld; + zOld = zOut; + zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1)); + if( zOut==0 ){ + sqlite3_result_error_nomem(context); + sqlite3_free(zOld); + return; + } + } } memcpy(&zOut[j], zRep, nRep); j += nRep; i += nPattern-1; } } - assert( j+nStr-i+1==nOut ); + assert( j+nStr-i+1<=nOut ); memcpy(&zOut[j], &zStr[i], nStr-i); j += nStr - i; assert( j<=nOut ); @@ -1487,7 +1505,7 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ i64 v = sqlite3_value_int64(argv[0]); p->rSum += v; if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ - p->overflow = 1; + p->approx = p->overflow = 1; } }else{ p->rSum += sqlite3_value_double(argv[0]); @@ -1495,6 +1513,32 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ } } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + /* p is always non-NULL because sumStep() will have been called first + ** to initialize it */ + if( ALWAYS(p) && type!=SQLITE_NULL ){ + assert( p->cnt>0 ); + p->cnt--; + assert( type==SQLITE_INTEGER || p->approx ); + if( type==SQLITE_INTEGER && p->approx==0 ){ + i64 v = sqlite3_value_int64(argv[0]); + p->rSum -= v; + p->iSum -= v; + }else{ + p->rSum -= sqlite3_value_double(argv[0]); + } + } +} +#else +# define sumInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ static void sumFinalize(sqlite3_context *context){ SumCtx *p; p = sqlite3_aggregate_context(context, 0); @@ -1529,6 +1573,9 @@ static void totalFinalize(sqlite3_context *context){ typedef struct CountCtx CountCtx; struct CountCtx { i64 n; +#ifdef SQLITE_DEBUG + int bInverse; /* True if xInverse() ever called */ +#endif }; /* @@ -1546,7 +1593,7 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ ** sure it still operates correctly, verify that its count agrees with our ** internal count when using count(*) and when the total count can be ** expressed as a 32-bit integer. */ - assert( argc==1 || p==0 || p->n>0x7fffffff + assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse || p->n==sqlite3_aggregate_count(context) ); #endif } @@ -1555,6 +1602,21 @@ static void countFinalize(sqlite3_context *context){ p = sqlite3_aggregate_context(context, 0); sqlite3_result_int64(context, p ? p->n : 0); } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(ctx, sizeof(*p)); + /* p is always non-NULL since countStep() will have been called first */ + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){ + p->n--; +#ifdef SQLITE_DEBUG + p->bInverse = 1; +#endif + } +} +#else +# define countInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** Routines to implement min() and max() aggregate functions. @@ -1571,7 +1633,7 @@ static void minmaxStep( pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); if( !pBest ) return; - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + if( sqlite3_value_type(pArg)==SQLITE_NULL ){ if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); }else if( pBest->flags ){ int max; @@ -1597,16 +1659,26 @@ static void minmaxStep( sqlite3VdbeMemCopy(pBest, pArg); } } -static void minMaxFinalize(sqlite3_context *context){ +static void minMaxValueFinalize(sqlite3_context *context, int bValue){ sqlite3_value *pRes; pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); if( pRes ){ if( pRes->flags ){ sqlite3_result_value(context, pRes); } - sqlite3VdbeMemRelease(pRes); + if( bValue==0 ) sqlite3VdbeMemRelease(pRes); } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void minMaxValue(sqlite3_context *context){ + minMaxValueFinalize(context, 1); +} +#else +# define minMaxValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void minMaxFinalize(sqlite3_context *context){ + minMaxValueFinalize(context, 0); +} /* ** group_concat(EXPR, ?SEPARATOR?) @@ -1636,20 +1708,52 @@ static void groupConcatStep( zSep = ","; nSep = 1; } - if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); + if( zSep ) sqlite3_str_append(pAccum, zSep, nSep); } zVal = (char*)sqlite3_value_text(argv[0]); nVal = sqlite3_value_bytes(argv[0]); - if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); + if( zVal ) sqlite3_str_append(pAccum, zVal, nVal); } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatInverse( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + StrAccum *pAccum; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); + /* pAccum is always non-NULL since groupConcatStep() will have always + ** run frist to initialize it */ + if( ALWAYS(pAccum) ){ + n = sqlite3_value_bytes(argv[0]); + if( argc==2 ){ + n += sqlite3_value_bytes(argv[1]); + }else{ + n++; + } + if( n>=(int)pAccum->nChar ){ + pAccum->nChar = 0; + }else{ + pAccum->nChar -= n; + memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar); + } + if( pAccum->nChar==0 ) pAccum->mxAlloc = 0; + } +} +#else +# define groupConcatInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ static void groupConcatFinalize(sqlite3_context *context){ StrAccum *pAccum; pAccum = sqlite3_aggregate_context(context, 0); if( pAccum ){ - if( pAccum->accError==STRACCUM_TOOBIG ){ + if( pAccum->accError==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(context); - }else if( pAccum->accError==STRACCUM_NOMEM ){ + }else if( pAccum->accError==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); }else{ sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, @@ -1657,6 +1761,24 @@ static void groupConcatFinalize(sqlite3_context *context){ } } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatValue(sqlite3_context *context){ + sqlite3_str *pAccum; + pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0); + if( pAccum ){ + if( pAccum->accError==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(context); + }else if( pAccum->accError==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + const char *zText = sqlite3_str_value(pAccum); + sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); + } + } +} +#else +# define groupConcatValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** This routine does per-connection function registration. Most @@ -1694,10 +1816,10 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ }else{ pInfo = (struct compareInfo*)&likeInfoNorm; } - sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); - sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, - (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0); + (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0); setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); setLikeOptFlag(db, "like", caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); @@ -1793,6 +1915,10 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), #ifdef SQLITE_DEBUG FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY), +#endif +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET| + SQLITE_FUNC_TYPEOF), #endif FUNCTION(ltrim, 1, 1, 0, trimFunc ), FUNCTION(ltrim, 2, 1, 0, trimFunc ), @@ -1802,11 +1928,11 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(trim, 2, 3, 0, trimFunc ), FUNCTION(min, -1, 0, 1, minmaxFunc ), FUNCTION(min, 0, 0, 1, 0 ), - AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize, + WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, SQLITE_FUNC_MINMAX ), FUNCTION(max, -1, 1, 1, minmaxFunc ), FUNCTION(max, 0, 1, 1, 0 ), - AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize, + WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, SQLITE_FUNC_MINMAX ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), @@ -1837,14 +1963,17 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), - AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), - AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), - AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), - AGGREGATE2(count, 0, 0, 0, countStep, countFinalize, - SQLITE_FUNC_COUNT ), - AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), - AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), - AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), + WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), + WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), + WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), + WAGGREGATE(count, 0,0,0, countStep, + countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT ), + WAGGREGATE(count, 1,0,0, countStep, + countFinalize, countFinalize, countInverse, 0 ), + WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE @@ -1864,6 +1993,7 @@ void sqlite3RegisterBuiltinFunctions(void){ #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); #endif + sqlite3WindowFunctions(); #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) sqlite3AnalyzeFunctions(); #endif diff --git a/src/global.c b/src/global.c index fe63bbe140..f0362d1e04 100644 --- a/src/global.c +++ b/src/global.c @@ -199,6 +199,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_THREADSAFE==1, /* bFullMutex */ SQLITE_USE_URI, /* bOpenUri */ SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ + 0, /* bSmallMalloc */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ @@ -211,9 +212,6 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, 0, /* mnHeap, mxHeap */ SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */ SQLITE_MAX_MMAP_SIZE, /* mxMmap */ - (void*)0, /* pScratch */ - 0, /* szScratch */ - 0, /* nScratch */ (void*)0, /* pPage */ 0, /* szPage */ SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */ @@ -242,7 +240,8 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ - 0x7ffffffe /* iOnceResetThreshold */ + 0x7ffffffe, /* iOnceResetThreshold */ + SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */ }; /* @@ -260,6 +259,13 @@ const Token sqlite3IntTokens[] = { { "1", 1 } }; +#ifdef VDBE_PROFILE +/* +** The following performance counter can be used in place of +** sqlite3Hwtime() for profiling. This is a no-op on standard builds. +*/ +sqlite3_uint64 sqlite3NProfileCnt = 0; +#endif /* ** The value of the "pending" byte must be 0x40000000 (1 byte past the diff --git a/src/insert.c b/src/insert.c index f8e9095ea5..d110ab7634 100644 --- a/src/insert.c +++ b/src/insert.c @@ -210,11 +210,12 @@ static int readsTable(Parse *p, int iDb, Table *pTab){ ** first use of table pTab. On 2nd and subsequent uses, the original ** AutoincInfo structure is used. ** -** Three memory locations are allocated: +** Four consecutive registers are allocated: ** -** (1) Register to hold the name of the pTab table. -** (2) Register to hold the maximum ROWID of pTab. -** (3) Register to hold the rowid in sqlite_sequence of pTab +** (1) The name of the pTab table. +** (2) The maximum ROWID of pTab. +** (3) The rowid in sqlite_sequence of pTab +** (4) The original value of the max ROWID in pTab, or NULL if none ** ** The 2nd register is the one that is returned. That is all the ** insert routine needs to know about. @@ -225,11 +226,26 @@ static int autoIncBegin( Table *pTab /* The table we are writing to */ ){ int memId = 0; /* Register holding maximum rowid */ + assert( pParse->db->aDb[iDb].pSchema!=0 ); if( (pTab->tabFlags & TF_Autoincrement)!=0 && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); AutoincInfo *pInfo; + Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab; + + /* Verify that the sqlite_sequence table exists and is an ordinary + ** rowid table with exactly two columns. + ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */ + if( pSeqTab==0 + || !HasRowid(pSeqTab) + || IsVirtual(pSeqTab) + || pSeqTab->nCol!=2 + ){ + pParse->nErr++; + pParse->rc = SQLITE_CORRUPT_SEQUENCE; + return 0; + } pInfo = pToplevel->pAinc; while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } @@ -242,7 +258,7 @@ static int autoIncBegin( pInfo->iDb = iDb; pToplevel->nMem++; /* Register to hold name of table */ pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ - pToplevel->nMem++; /* Rowid in sqlite_sequence */ + pToplevel->nMem +=2; /* Rowid in sqlite_sequence + orig max val */ } memId = pInfo->regCtr; } @@ -270,15 +286,17 @@ void sqlite3AutoincrementBegin(Parse *pParse){ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList autoInc[] = { /* 0 */ {OP_Null, 0, 0, 0}, - /* 1 */ {OP_Rewind, 0, 9, 0}, + /* 1 */ {OP_Rewind, 0, 10, 0}, /* 2 */ {OP_Column, 0, 0, 0}, - /* 3 */ {OP_Ne, 0, 7, 0}, + /* 3 */ {OP_Ne, 0, 9, 0}, /* 4 */ {OP_Rowid, 0, 0, 0}, /* 5 */ {OP_Column, 0, 1, 0}, - /* 6 */ {OP_Goto, 0, 9, 0}, - /* 7 */ {OP_Next, 0, 2, 0}, - /* 8 */ {OP_Integer, 0, 0, 0}, - /* 9 */ {OP_Close, 0, 0, 0} + /* 6 */ {OP_AddImm, 0, 0, 0}, + /* 7 */ {OP_Copy, 0, 0, 0}, + /* 8 */ {OP_Goto, 0, 11, 0}, + /* 9 */ {OP_Next, 0, 2, 0}, + /* 10 */ {OP_Integer, 0, 0, 0}, + /* 11 */ {OP_Close, 0, 0, 0} }; VdbeOp *aOp; pDb = &db->aDb[p->iDb]; @@ -289,14 +307,17 @@ void sqlite3AutoincrementBegin(Parse *pParse){ aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); if( aOp==0 ) break; aOp[0].p2 = memId; - aOp[0].p3 = memId+1; + aOp[0].p3 = memId+2; aOp[2].p3 = memId; aOp[3].p1 = memId-1; aOp[3].p3 = memId; aOp[3].p5 = SQLITE_JUMPIFNULL; aOp[4].p2 = memId+1; aOp[5].p3 = memId; - aOp[8].p2 = memId; + aOp[6].p1 = memId; + aOp[7].p2 = memId+2; + aOp[7].p1 = memId; + aOp[10].p2 = memId; } } @@ -343,6 +364,8 @@ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ iRec = sqlite3GetTempReg(pParse); assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId); + VdbeCoverage(v); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); if( aOp==0 ) break; @@ -480,11 +503,11 @@ void sqlite3Insert( SrcList *pTabList, /* Name of table into which we are inserting */ Select *pSelect, /* A SELECT statement to use as the data source */ IdList *pColumn, /* Column names corresponding to IDLIST. */ - int onError /* How to handle constraint errors */ + int onError, /* How to handle constraint errors */ + Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */ ){ sqlite3 *db; /* The main database structure */ Table *pTab; /* The table to insert into. aka TABLE */ - char *zTab; /* Name of the table into which we are inserting */ int i, j; /* Loop counters */ Vdbe *v; /* Generate code into this virtual machine */ Index *pIdx; /* For looping over indices of the table */ @@ -540,8 +563,6 @@ void sqlite3Insert( /* Locate the table into which we will be inserting new information. */ assert( pTabList->nSrc==1 ); - zTab = pTabList->a[0].zName; - if( NEVER(zTab==0) ) goto insert_cleanup; pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ){ goto insert_cleanup; @@ -778,7 +799,10 @@ void sqlite3Insert( /* Initialize the count of rows to be inserted */ - if( db->flags & SQLITE_CountRows ){ + if( (db->flags & SQLITE_CountRows)!=0 + && !pParse->nested + && !pParse->pTriggerTab + ){ regRowCount = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); } @@ -798,6 +822,19 @@ void sqlite3Insert( pParse->nMem += pIdx->nColumn; } } +#ifndef SQLITE_OMIT_UPSERT + if( pUpsert ){ + pTabList->a[0].iCursor = iDataCur; + pUpsert->pUpsertSrc = pTabList; + pUpsert->regData = regData; + pUpsert->iDataCur = iDataCur; + pUpsert->iIdxCur = iIdxCur; + if( pUpsert->pUpsertTarget ){ + sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); + } + } +#endif + /* This is the top of the main insertion loop */ if( useTempTable ){ @@ -912,7 +949,8 @@ void sqlite3Insert( VdbeOp *pOp; sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); pOp = sqlite3VdbeGetOp(v, -1); - if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){ + assert( pOp!=0 ); + if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){ appendFlag = 1; pOp->opcode = OP_NewRowid; pOp->p1 = iDataCur; @@ -999,7 +1037,7 @@ void sqlite3Insert( int isReplace; /* Set to true if constraints may cause a replace */ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, - regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0 + regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert ); sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); @@ -1022,7 +1060,7 @@ void sqlite3Insert( /* Update the count of rows that are inserted */ - if( (db->flags & SQLITE_CountRows)!=0 ){ + if( regRowCount ){ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } @@ -1059,7 +1097,7 @@ insert_end: ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ - if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ + if( regRowCount ){ sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); @@ -1068,6 +1106,7 @@ insert_end: insert_cleanup: sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pList); + sqlite3UpsertDelete(db, pUpsert); sqlite3SelectDelete(db, pSelect); sqlite3IdListDelete(db, pColumn); sqlite3DbFree(db, aRegIdx); @@ -1087,14 +1126,15 @@ insert_cleanup: #endif /* -** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged() +** Meanings of bits in of pWalker->eCode for +** sqlite3ExprReferencesUpdatedColumn() */ #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ -/* This is the Walker callback from checkConstraintUnchanged(). Set -** bit 0x01 of pWalker->eCode if -** pWalker->eCode to 0 if this expression node references any of the +/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). +* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this +** expression node references any of the ** columns that are being modifed by an UPDATE statement. */ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ @@ -1116,12 +1156,21 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ ** only columns that are modified by the UPDATE are those for which ** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true. ** -** Return true if CHECK constraint pExpr does not use any of the +** Return true if CHECK constraint pExpr uses any of the ** changing columns (or the rowid if it is changing). In other words, -** return true if this CHECK constraint can be skipped when validating +** return true if this CHECK constraint must be validated for ** the new row in the UPDATE statement. +** +** 2018-09-15: pExpr might also be an expression for an index-on-expressions. +** The operation of this routine is the same - return true if an only if +** the expression uses one or more of columns identified by the second and +** third arguments. */ -static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){ +int sqlite3ExprReferencesUpdatedColumn( + Expr *pExpr, /* The expression to be checked */ + int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */ + int chngRowid /* True if UPDATE changes the rowid */ +){ Walker w; memset(&w, 0, sizeof(w)); w.eCode = 0; @@ -1136,7 +1185,7 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){ testcase( w.eCode==CKCNSTRNT_COLUMN ); testcase( w.eCode==CKCNSTRNT_ROWID ); testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) ); - return !w.eCode; + return w.eCode!=0; } /* @@ -1234,7 +1283,8 @@ void sqlite3GenerateConstraintChecks( u8 overrideError, /* Override onError to this if not OE_Default */ int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */ - int *aiChng /* column i is unchanged if aiChng[i]<0 */ + int *aiChng, /* column i is unchanged if aiChng[i]<0 */ + Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ ){ Vdbe *v; /* VDBE under constrution */ Index *pIdx; /* Pointer to one of the indices */ @@ -1247,10 +1297,13 @@ void sqlite3GenerateConstraintChecks( int addr1; /* Address of jump instruction */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ - int ipkTop = 0; /* Top of the rowid change constraint check */ - int ipkBottom = 0; /* Bottom of the rowid change constraint check */ + Index *pUpIdx = 0; /* Index to which to apply the upsert */ u8 isUpdate; /* True if this is an UPDATE operation */ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ + int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */ + int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */ + int ipkTop = 0; /* Top of the IPK uniqueness check */ + int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ isUpdate = regOldData!=0; db = pParse->db; @@ -1338,8 +1391,15 @@ void sqlite3GenerateConstraintChecks( for(i=0; inExpr; i++){ int allOk; Expr *pExpr = pCheck->a[i].pExpr; - if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue; + if( aiChng + && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng) + ){ + /* The check constraints do not reference any of the columns being + ** updated so there is no point it verifying the check constraint */ + continue; + } allOk = sqlite3VdbeMakeLabel(v); + sqlite3VdbeVerifyAbortable(v, onError); sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); if( onError==OE_Ignore ){ sqlite3VdbeGoto(v, ignoreDest); @@ -1357,6 +1417,50 @@ void sqlite3GenerateConstraintChecks( } #endif /* !defined(SQLITE_OMIT_CHECK) */ + /* UNIQUE and PRIMARY KEY constraints should be handled in the following + ** order: + ** + ** (1) OE_Update + ** (2) OE_Abort, OE_Fail, OE_Rollback, OE_Ignore + ** (3) OE_Replace + ** + ** OE_Fail and OE_Ignore must happen before any changes are made. + ** OE_Update guarantees that only a single row will change, so it + ** must happen before OE_Replace. Technically, OE_Abort and OE_Rollback + ** could happen in any order, but they are grouped up front for + ** convenience. + ** + ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43 + ** The order of constraints used to have OE_Update as (2) and OE_Abort + ** and so forth as (1). But apparently PostgreSQL checks the OE_Update + ** constraint before any others, so it had to be moved. + ** + ** Constraint checking code is generated in this order: + ** (A) The rowid constraint + ** (B) Unique index constraints that do not have OE_Replace as their + ** default conflict resolution strategy + ** (C) Unique index that do use OE_Replace by default. + ** + ** The ordering of (2) and (3) is accomplished by making sure the linked + ** list of indexes attached to a table puts all OE_Replace indexes last + ** in the list. See sqlite3CreateIndex() for where that happens. + */ + + if( pUpsert ){ + if( pUpsert->pUpsertTarget==0 ){ + /* An ON CONFLICT DO NOTHING clause, without a constraint-target. + ** Make all unique constraint resolution be OE_Ignore */ + assert( pUpsert->pUpsertSet==0 ); + overrideError = OE_Ignore; + pUpsert = 0; + }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){ + /* If the constraint-target uniqueness check must be run first. + ** Jump to that uniqueness check now */ + upsertJump = sqlite3VdbeAddOp0(v, OP_Goto); + VdbeComment((v, "UPSERT constraint goes first")); + } + } + /* If rowid is changing, make sure the new rowid does not previously ** exist in the table. */ @@ -1371,6 +1475,28 @@ void sqlite3GenerateConstraintChecks( onError = OE_Abort; } + /* figure out whether or not upsert applies in this case */ + if( pUpsert && pUpsert->pUpsertIdx==0 ){ + if( pUpsert->pUpsertSet==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + + /* If the response to a rowid conflict is REPLACE but the response + ** to some other UNIQUE constraint is FAIL or IGNORE, then we need + ** to defer the running of the rowid conflict checking until after + ** the UNIQUE constraints have run. + */ + if( onError==OE_Replace /* IPK rule is REPLACE */ + && onError!=overrideError /* Rules for other contraints are different */ + && pTab->pIndex /* There exist other constraints */ + ){ + ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; + VdbeComment((v, "defer IPK REPLACE until last")); + } + if( isUpdate ){ /* pkChng!=0 does not mean that the rowid has changed, only that ** it might have changed. Skip the conflict logic below if the rowid @@ -1380,26 +1506,13 @@ void sqlite3GenerateConstraintChecks( VdbeCoverage(v); } - /* If the response to a rowid conflict is REPLACE but the response - ** to some other UNIQUE constraint is FAIL or IGNORE, then we need - ** to defer the running of the rowid conflict checking until after - ** the UNIQUE constraints have run. - */ - if( onError==OE_Replace && overrideError!=OE_Replace ){ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){ - ipkTop = sqlite3VdbeAddOp0(v, OP_Goto); - break; - } - } - } - /* Check to see if the new rowid already exists in the table. Skip ** the following conflict logic if it does not. */ + VdbeNoopComment((v, "uniqueness check for ROWID")); + sqlite3VdbeVerifyAbortable(v, onError); sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); VdbeCoverage(v); - /* Generate code that deals with a rowid collision */ switch( onError ){ default: { onError = OE_Abort; @@ -1408,6 +1521,9 @@ void sqlite3GenerateConstraintChecks( case OE_Rollback: case OE_Abort: case OE_Fail: { + testcase( onError==OE_Rollback ); + testcase( onError==OE_Abort ); + testcase( onError==OE_Fail ); sqlite3RowidConstraint(pParse, onError, pTab); break; } @@ -1444,14 +1560,13 @@ void sqlite3GenerateConstraintChecks( regNewData, 1, 0, OE_Replace, 1, -1); }else{ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - if( HasRowid(pTab) ){ - /* This OP_Delete opcode fires the pre-update-hook only. It does - ** not modify the b-tree. It is more efficient to let the coming - ** OP_Insert replace the existing entry than it is to delete the - ** existing entry and then insert a new one. */ - sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); - sqlite3VdbeAppendP4(v, pTab, P4_TABLE); - } + assert( HasRowid(pTab) ); + /* This OP_Delete opcode fires the pre-update-hook only. It does + ** not modify the b-tree. It is more efficient to let the coming + ** OP_Insert replace the existing entry than it is to delete the + ** existing entry and then insert a new one. */ + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ if( pTab->pIndex ){ sqlite3MultiWrite(pParse); @@ -1461,8 +1576,14 @@ void sqlite3GenerateConstraintChecks( seenReplace = 1; break; } +#ifndef SQLITE_OMIT_UPSERT + case OE_Update: { + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur); + /* Fall through */ + } +#endif case OE_Ignore: { - /*assert( seenReplace==0 );*/ + testcase( onError==OE_Ignore ); sqlite3VdbeGoto(v, ignoreDest); break; } @@ -1470,7 +1591,7 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeResolveLabel(v, addrRowidOk); if( ipkTop ){ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeJumpHere(v, ipkTop); + sqlite3VdbeJumpHere(v, ipkTop-1); } } @@ -1488,12 +1609,21 @@ void sqlite3GenerateConstraintChecks( int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ - if( bAffinityDone==0 ){ + if( pUpIdx==pIdx ){ + addrUniqueOk = upsertJump+1; + upsertBypass = sqlite3VdbeGoto(v, 0); + VdbeComment((v, "Skip upsert subroutine")); + sqlite3VdbeJumpHere(v, upsertJump); + }else{ + addrUniqueOk = sqlite3VdbeMakeLabel(v); + } + if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } + VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName)); iThisCur = iIdxCur+ix; - addrUniqueOk = sqlite3VdbeMakeLabel(v); + /* Skip partial indices for which the WHERE clause is not true */ if( pIdx->pPartIdxWhere ){ @@ -1553,6 +1683,15 @@ void sqlite3GenerateConstraintChecks( onError = OE_Abort; } + /* Figure out if the upsert clause applies to this index */ + if( pUpIdx==pIdx ){ + if( pUpsert->pUpsertSet==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + /* Collision detection may be omitted if all of the following are true: ** (1) The conflict resolution algorithm is REPLACE ** (2) The table is a WITHOUT ROWID table @@ -1573,6 +1712,7 @@ void sqlite3GenerateConstraintChecks( } /* Check to see if the new index entry will be unique */ + sqlite3VdbeVerifyAbortable(v, onError); sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, regIdx, pIdx->nKeyCol); VdbeCoverage(v); @@ -1634,25 +1774,37 @@ void sqlite3GenerateConstraintChecks( /* Generate code that executes if the new index entry is not unique */ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail - || onError==OE_Ignore || onError==OE_Replace ); + || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update ); switch( onError ){ case OE_Rollback: case OE_Abort: case OE_Fail: { + testcase( onError==OE_Rollback ); + testcase( onError==OE_Abort ); + testcase( onError==OE_Fail ); sqlite3UniqueConstraint(pParse, onError, pIdx); break; } +#ifndef SQLITE_OMIT_UPSERT + case OE_Update: { + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix); + /* Fall through */ + } +#endif case OE_Ignore: { + testcase( onError==OE_Ignore ); sqlite3VdbeGoto(v, ignoreDest); break; } default: { Trigger *pTrigger = 0; assert( onError==OE_Replace ); - sqlite3MultiWrite(pParse); if( db->flags&SQLITE_RecTriggers ){ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); } + if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ + sqlite3MultiWrite(pParse); + } sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regR, nPkField, 0, OE_Replace, (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); @@ -1660,14 +1812,22 @@ void sqlite3GenerateConstraintChecks( break; } } - sqlite3VdbeResolveLabel(v, addrUniqueOk); + if( pUpIdx==pIdx ){ + sqlite3VdbeGoto(v, upsertJump+1); + sqlite3VdbeJumpHere(v, upsertBypass); + }else{ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + } if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); } + + /* If the IPK constraint is a REPLACE, run it last */ if( ipkTop ){ sqlite3VdbeGoto(v, ipkTop+1); + VdbeComment((v, "Do IPK REPLACE")); sqlite3VdbeJumpHere(v, ipkBottom); } - + *pbMayReplace = seenReplace; VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); } @@ -1763,7 +1923,6 @@ void sqlite3CompleteInsertion( sqlite3SetMakeRecordP5(v, pTab); if( !bAffinityDone ){ sqlite3TableAffinity(v, pTab, 0); - sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); } if( pParse->nested ){ pik_flags = 0; @@ -2009,7 +2168,6 @@ static int xferOptimization( if( pSelect->pLimit ){ return 0; /* SELECT may not have a LIMIT clause */ } - assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ if( pSelect->pPrior ){ return 0; /* SELECT may not be a compound query */ } @@ -2167,6 +2325,7 @@ static int xferOptimization( emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + sqlite3VdbeVerifyAbortable(v, onError); addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); VdbeCoverage(v); sqlite3RowidConstraint(pParse, onError, pDest); diff --git a/src/loadext.c b/src/loadext.c index 6751425936..72bfd5c51e 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -430,7 +430,28 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_prepare16_v3, sqlite3_bind_pointer, sqlite3_result_pointer, - sqlite3_value_pointer + sqlite3_value_pointer, + /* Version 3.22.0 and later */ + sqlite3_vtab_nochange, + sqlite3_value_nochange, + sqlite3_vtab_collation, + /* Version 3.24.0 and later */ + sqlite3_keyword_count, + sqlite3_keyword_name, + sqlite3_keyword_check, + sqlite3_str_new, + sqlite3_str_finish, + sqlite3_str_appendf, + sqlite3_str_vappendf, + sqlite3_str_append, + sqlite3_str_appendall, + sqlite3_str_appendchar, + sqlite3_str_reset, + sqlite3_str_errcode, + sqlite3_str_length, + sqlite3_str_value, + /* Version 3.25.0 and later */ + sqlite3_create_window_function }; /* diff --git a/src/main.c b/src/main.c index 10cb5cef8a..5584dc2906 100644 --- a/src/main.c +++ b/src/main.c @@ -22,7 +22,7 @@ #ifdef SQLITE_ENABLE_RTREE # include "rtree.h" #endif -#ifdef SQLITE_ENABLE_ICU +#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) # include "sqliteicu.h" #endif #ifdef SQLITE_ENABLE_JSON1 @@ -47,9 +47,11 @@ const char sqlite3_version[] = SQLITE_VERSION; */ const char *sqlite3_libversion(void){ return sqlite3_version; } -/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a +/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a ** pointer to a string constant whose value is the same as the -** SQLITE_SOURCE_ID C preprocessor macro. +** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using +** an edited copy of the amalgamation, then the last four characters of +** the hash might be different from SQLITE_SOURCE_ID. */ const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } @@ -237,6 +239,11 @@ int sqlite3_initialize(void){ sqlite3GlobalConfig.isPCacheInit = 1; rc = sqlite3OsInit(); } +#ifdef SQLITE_ENABLE_DESERIALIZE + if( rc==SQLITE_OK ){ + rc = sqlite3MemdbInit(); + } +#endif if( rc==SQLITE_OK ){ sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); @@ -269,7 +276,7 @@ int sqlite3_initialize(void){ #ifndef NDEBUG #ifndef SQLITE_OMIT_FLOATING_POINT /* This section of code's only "output" is via assert() statements. */ - if ( rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ u64 x = (((u64)1)<<63)-1; double y; assert(sizeof(x)==8); @@ -436,14 +443,8 @@ int sqlite3_config(int op, ...){ sqlite3GlobalConfig.bMemstat = va_arg(ap, int); break; } - case SQLITE_CONFIG_SCRATCH: { - /* EVIDENCE-OF: R-08404-60887 There are three arguments to - ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from - ** which the scratch allocations will be drawn, the size of each scratch - ** allocation (sz), and the maximum number of scratch allocations (N). */ - sqlite3GlobalConfig.pScratch = va_arg(ap, void*); - sqlite3GlobalConfig.szScratch = va_arg(ap, int); - sqlite3GlobalConfig.nScratch = va_arg(ap, int); + case SQLITE_CONFIG_SMALL_MALLOC: { + sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int); break; } case SQLITE_CONFIG_PAGECACHE: { @@ -641,6 +642,17 @@ int sqlite3_config(int op, ...){ break; } +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + case SQLITE_CONFIG_SORTERREF_SIZE: { + int iVal = va_arg(ap, int); + if( iVal<0 ){ + iVal = SQLITE_DEFAULT_SORTERREF_SIZE; + } + sqlite3GlobalConfig.szSorterRef = (u32)iVal; + break; + } +#endif /* SQLITE_ENABLE_SORTER_REFERENCES */ + default: { rc = SQLITE_ERROR; break; @@ -664,7 +676,8 @@ int sqlite3_config(int op, ...){ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ #ifndef SQLITE_OMIT_LOOKASIDE void *pStart; - if( db->lookaside.nOut ){ + + if( sqlite3LookasideUsed(db,0)>0 ){ return SQLITE_BUSY; } /* Free any existing lookaside buffer for this handle before @@ -692,16 +705,18 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ pStart = pBuf; } db->lookaside.pStart = pStart; + db->lookaside.pInit = 0; db->lookaside.pFree = 0; db->lookaside.sz = (u16)sz; if( pStart ){ int i; LookasideSlot *p; assert( sz > (int)sizeof(LookasideSlot*) ); + db->lookaside.nSlot = cnt; p = (LookasideSlot*)pStart; for(i=cnt-1; i>=0; i--){ - p->pNext = db->lookaside.pFree; - db->lookaside.pFree = p; + p->pNext = db->lookaside.pInit; + db->lookaside.pInit = p; p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; @@ -712,6 +727,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ db->lookaside.pEnd = db; db->lookaside.bDisable = 1; db->lookaside.bMalloced = 0; + db->lookaside.nSlot = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; @@ -817,6 +833,8 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, + { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, + { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -831,7 +849,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ db->flags &= ~aFlagOp[i].mask; } if( oldFlags!=db->flags ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); } if( pRes ){ *pRes = (db->flags & aFlagOp[i].mask)!=0; @@ -892,6 +910,15 @@ static int binCollFunc( return rc; } +/* +** Return true if CollSeq is the default built-in BINARY. +*/ +int sqlite3IsBinary(const CollSeq *p){ + assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0 + || strcmp(p->zName,"BINARY")==0 ); + return p==0 || (p->xCmp==binCollFunc && p->pUser==0); +} + /* ** Another built-in collating sequence: NOCASE. ** @@ -1013,7 +1040,7 @@ static void disconnectAllVtab(sqlite3 *db){ sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Schema *pSchema = db->aDb[i].pSchema; - if( db->aDb[i].pSchema ){ + if( pSchema ){ for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ Table *pTab = (Table *)sqliteHashData(p); if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); @@ -1235,7 +1262,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3_mutex_leave(db->mutex); db->magic = SQLITE_MAGIC_CLOSED; sqlite3_mutex_free(db->mutex); - assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */ + assert( sqlite3LookasideUsed(db,0)==0 ); if( db->lookaside.bMalloced ){ sqlite3_free(db->lookaside.pStart); } @@ -1277,8 +1304,8 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ sqlite3VtabRollback(db); sqlite3EndBenignMalloc(); - if( (db->mDbFlags&DBFLAG_SchemaChange)!=0 && db->init.busy==0 ){ - sqlite3ExpirePreparedStatements(db); + if( schemaChange ){ + sqlite3ExpirePreparedStatements(db, 0); sqlite3ResetAllSchemasOfConnection(db); } sqlite3BtreeLeaveAll(db); @@ -1306,6 +1333,7 @@ const char *sqlite3ErrName(int rc){ switch( rc ){ case SQLITE_OK: zName = "SQLITE_OK"; break; case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; + case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break; case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; case SQLITE_PERM: zName = "SQLITE_PERM"; break; case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; @@ -1318,9 +1346,10 @@ const char *sqlite3ErrName(int rc){ case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; - case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; + case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break; case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; + case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break; case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; @@ -1440,6 +1469,8 @@ const char *sqlite3ErrStr(int rc){ /* SQLITE_FORMAT */ 0, /* SQLITE_RANGE */ "column index out of range", /* SQLITE_NOTADB */ "file is not a database", + /* SQLITE_NOTICE */ "notification message", + /* SQLITE_WARNING */ "warning message", }; const char *zErr = "unknown error"; switch( rc ){ @@ -1447,6 +1478,14 @@ const char *sqlite3ErrStr(int rc){ zErr = "abort due to ROLLBACK"; break; } + case SQLITE_ROW: { + zErr = "another row available"; + break; + } + case SQLITE_DONE: { + zErr = "no more rows available"; + break; + } default: { rc &= 0xff; if( ALWAYS(rc>=0) && rcbusyTimeout; + int tmout = db->busyTimeout; int delay, prior; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){ + if( count ){ + tmout = 0; + sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout); + return 0; + }else{ + return 1; + } + } +#else + UNUSED_PARAMETER(pFile); +#endif assert( count>=0 ); if( count < NDELAY ){ delay = delays[count]; @@ -1486,16 +1544,19 @@ static int sqliteDefaultBusyCallback( delay = delays[NDELAY-1]; prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); } - if( prior + delay > timeout ){ - delay = timeout - prior; + if( prior + delay > tmout ){ + delay = tmout - prior; if( delay<=0 ) return 0; } sqlite3OsSleep(db->pVfs, delay*1000); return 1; #else + /* This case for unix systems that lack usleep() support. Sleeping + ** must be done in increments of whole seconds */ sqlite3 *db = (sqlite3 *)ptr; - int timeout = ((sqlite3 *)ptr)->busyTimeout; - if( (count+1)*1000 > timeout ){ + int tmout = ((sqlite3 *)ptr)->busyTimeout; + UNUSED_PARAMETER(pFile); + if( (count+1)*1000 > tmout ){ return 0; } sqlite3OsSleep(db->pVfs, 1000000); @@ -1506,14 +1567,25 @@ static int sqliteDefaultBusyCallback( /* ** Invoke the given busy handler. ** -** This routine is called when an operation failed with a lock. +** This routine is called when an operation failed to acquire a +** lock on VFS file pFile. +** ** If this routine returns non-zero, the lock is retried. If it ** returns 0, the operation aborts with an SQLITE_BUSY error. */ -int sqlite3InvokeBusyHandler(BusyHandler *p){ +int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){ int rc; - if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0; - rc = p->xFunc(p->pArg, p->nBusy); + if( p->xBusyHandler==0 || p->nBusy<0 ) return 0; + if( p->bExtraFileArg ){ + /* Add an extra parameter with the pFile pointer to the end of the + ** callback argument list */ + int (*xTra)(void*,int,sqlite3_file*); + xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler; + rc = xTra(p->pBusyArg, p->nBusy, pFile); + }else{ + /* Legacy style busy handler callback */ + rc = p->xBusyHandler(p->pBusyArg, p->nBusy); + } if( rc==0 ){ p->nBusy = -1; }else{ @@ -1535,9 +1607,10 @@ int sqlite3_busy_handler( if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); - db->busyHandler.xFunc = xBusy; - db->busyHandler.pArg = pArg; + db->busyHandler.xBusyHandler = xBusy; + db->busyHandler.pBusyArg = pArg; db->busyHandler.nBusy = 0; + db->busyHandler.bExtraFileArg = 0; db->busyTimeout = 0; sqlite3_mutex_leave(db->mutex); return SQLITE_OK; @@ -1585,8 +1658,10 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif if( ms>0 ){ - sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); + sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, + (void*)db); db->busyTimeout = ms; + db->busyHandler.bExtraFileArg = 1; }else{ sqlite3_busy_handler(db, 0, 0); } @@ -1622,6 +1697,8 @@ int sqlite3CreateFunc( void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), FuncDestructor *pDestructor ){ FuncDef *p; @@ -1629,12 +1706,14 @@ int sqlite3CreateFunc( int extraFlags; assert( sqlite3_mutex_held(db->mutex) ); - if( zFunctionName==0 || - (xSFunc && (xFinal || xStep)) || - (!xSFunc && (xFinal && !xStep)) || - (!xSFunc && (!xFinal && xStep)) || - (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || - (255<(nName = sqlite3Strlen30( zFunctionName))) ){ + assert( xValue==0 || xSFunc==0 ); + if( zFunctionName==0 /* Must have a valid name */ + || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */ + || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ + || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ + || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) + || (255<(nName = sqlite3Strlen30( zFunctionName))) + ){ return SQLITE_MISUSE_BKPT; } @@ -1655,10 +1734,10 @@ int sqlite3CreateFunc( }else if( enc==SQLITE_ANY ){ int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, - pUserData, xSFunc, xStep, xFinal, pDestructor); + pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, - pUserData, xSFunc, xStep, xFinal, pDestructor); + pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); } if( rc!=SQLITE_OK ){ return rc; @@ -1675,14 +1754,14 @@ int sqlite3CreateFunc( ** operation to continue but invalidate all precompiled statements. */ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); - if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ + if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ if( db->nVdbeActive ){ sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify user-function due to active statements"); assert( !db->mallocFailed ); return SQLITE_BUSY; }else{ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); } } @@ -1704,11 +1783,68 @@ int sqlite3CreateFunc( testcase( p->funcFlags & SQLITE_DETERMINISTIC ); p->xSFunc = xSFunc ? xSFunc : xStep; p->xFinalize = xFinal; + p->xValue = xValue; + p->xInverse = xInverse; p->pUserData = pUserData; p->nArg = (u16)nArg; return SQLITE_OK; } +/* +** Worker function used by utf-8 APIs that create new functions: +** +** sqlite3_create_function() +** sqlite3_create_function_v2() +** sqlite3_create_window_function() +*/ +static int createFunctionApi( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +){ + int rc = SQLITE_ERROR; + FuncDestructor *pArg = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( xDestroy ){ + pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor)); + if( !pArg ){ + sqlite3OomFault(db); + xDestroy(p); + goto out; + } + pArg->nRef = 0; + pArg->xDestroy = xDestroy; + pArg->pUserData = p; + } + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, + xSFunc, xStep, xFinal, xValue, xInverse, pArg + ); + if( pArg && pArg->nRef==0 ){ + assert( rc!=SQLITE_OK ); + xDestroy(p); + sqlite3_free(pArg); + } + + out: + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + /* ** Create new user functions. */ @@ -1722,10 +1858,9 @@ int sqlite3_create_function( void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*) ){ - return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep, - xFinal, 0); + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, 0); } - int sqlite3_create_function_v2( sqlite3 *db, const char *zFunc, @@ -1737,35 +1872,23 @@ int sqlite3_create_function_v2( void (*xFinal)(sqlite3_context*), void (*xDestroy)(void *) ){ - int rc = SQLITE_ERROR; - FuncDestructor *pArg = 0; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - if( xDestroy ){ - pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor)); - if( !pArg ){ - xDestroy(p); - goto out; - } - pArg->xDestroy = xDestroy; - pArg->pUserData = p; - } - rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg); - if( pArg && pArg->nRef==0 ){ - assert( rc!=SQLITE_OK ); - xDestroy(p); - sqlite3DbFree(db, pArg); - } - - out: - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, xDestroy); +} +int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), + void (*xDestroy)(void *) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep, + xFinal, xValue, xInverse, xDestroy); } #ifndef SQLITE_OMIT_UTF16 @@ -1788,7 +1911,7 @@ int sqlite3_create_function16( sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); - rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0); sqlite3DbFree(db, zFunc8); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); @@ -1797,6 +1920,28 @@ int sqlite3_create_function16( #endif +/* +** The following is the implementation of an SQL function that always +** fails with an error message stating that the function is used in the +** wrong context. The sqlite3_overload_function() API might construct +** SQL function that use this routine so that the functions will exist +** for name resolution but are actually overloaded by the xFindFunction +** method of virtual tables. +*/ +static void sqlite3InvalidFunction( + sqlite3_context *context, /* The function calling context */ + int NotUsed, /* Number of arguments to the function */ + sqlite3_value **NotUsed2 /* Value of each argument */ +){ + const char *zName = (const char*)sqlite3_user_data(context); + char *zErr; + UNUSED_PARAMETER2(NotUsed, NotUsed2); + zErr = sqlite3_mprintf( + "unable to use function %s in the requested context", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); +} + /* ** Declare that a function has been overloaded by a virtual table. ** @@ -1814,7 +1959,8 @@ int sqlite3_overload_function( const char *zName, int nArg ){ - int rc = SQLITE_OK; + int rc; + char *zCopy; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ @@ -1822,13 +1968,13 @@ int sqlite3_overload_function( } #endif sqlite3_mutex_enter(db->mutex); - if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){ - rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, - 0, sqlite3InvalidFunction, 0, 0, 0); - } - rc = sqlite3ApiExit(db, rc); + rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; sqlite3_mutex_leave(db->mutex); - return rc; + if( rc ) return SQLITE_OK; + zCopy = sqlite3_mprintf(zName); + if( zCopy==0 ) return SQLITE_NOMEM; + return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, + zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); } #ifndef SQLITE_OMIT_TRACE @@ -2179,7 +2325,8 @@ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ ** checkpointed. If an error is encountered it is returned immediately - ** no attempt is made to checkpoint any remaining databases. ** -** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART +** or TRUNCATE. */ int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ int rc = SQLITE_OK; /* Return code */ @@ -2389,7 +2536,7 @@ static int createCollation( "unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); /* If collation sequence pColl was created directly by a call to ** sqlite3_create_collation, and not generated by synthCollSeq(), @@ -2825,6 +2972,7 @@ static int openDatabase( }else{ isThreadsafe = sqlite3GlobalConfig.bFullMutex; } + if( flags & SQLITE_OPEN_PRIVATECACHE ){ flags &= ~SQLITE_OPEN_SHAREDCACHE; }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ @@ -2857,19 +3005,27 @@ static int openDatabase( /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; - if( isThreadsafe ){ + if( isThreadsafe +#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS + || sqlite3GlobalConfig.bCoreMutex +#endif + ){ db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); if( db->mutex==0 ){ sqlite3_free(db); db = 0; goto opendb_out; } + if( isThreadsafe==0 ){ + sqlite3MutexWarnOnContention(db->mutex); + } } sqlite3_mutex_enter(db->mutex); db->errMask = 0xff; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; + db->lookaside.bDisable = 1; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); @@ -3045,7 +3201,7 @@ static int openDatabase( } #endif -#ifdef SQLITE_ENABLE_ICU +#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) if( !db->mallocFailed && rc==SQLITE_OK ){ rc = sqlite3IcuInit(db); } @@ -3057,6 +3213,12 @@ static int openDatabase( } #endif +#ifdef SQLITE_ENABLE_DBPAGE_VTAB + if( !db->mallocFailed && rc==SQLITE_OK){ + rc = sqlite3DbpageRegister(db); + } +#endif + #ifdef SQLITE_ENABLE_DBSTAT_VTAB if( !db->mallocFailed && rc==SQLITE_OK){ rc = sqlite3DbstatRegister(db); @@ -3341,37 +3503,37 @@ int sqlite3_get_autocommit(sqlite3 *db){ ** 2. Invoke sqlite3_log() to provide the source code location where ** a low-level error is first detected. */ -static int reportError(int iErr, int lineno, const char *zType){ +int sqlite3ReportError(int iErr, int lineno, const char *zType){ sqlite3_log(iErr, "%s at line %d of [%.10s]", zType, lineno, 20+sqlite3_sourceid()); return iErr; } int sqlite3CorruptError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_CORRUPT, lineno, "database corruption"); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption"); } int sqlite3MisuseError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_MISUSE, lineno, "misuse"); + return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse"); } int sqlite3CantopenError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_CANTOPEN, lineno, "cannot open file"); + return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file"); } #ifdef SQLITE_DEBUG int sqlite3CorruptPgnoError(int lineno, Pgno pgno){ char zMsg[100]; sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno); testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_CORRUPT, lineno, zMsg); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); } int sqlite3NomemError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_NOMEM, lineno, "OOM"); + return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM"); } int sqlite3IoerrnomemError(int lineno){ testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); + return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); } #endif @@ -3564,10 +3726,11 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); rc = SQLITE_OK; - }else if( fd->pMethods ){ - rc = sqlite3OsFileControl(fd, op, pArg); + }else if( op==SQLITE_FCNTL_DATA_VERSION ){ + *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager); + rc = SQLITE_OK; }else{ - rc = SQLITE_NOTFOUND; + rc = sqlite3OsFileControl(fd, op, pArg); } sqlite3BtreeLeave(pBtree); } @@ -3716,7 +3879,7 @@ int sqlite3_test_control(int op, ...){ ** This action provides a run-time test to see how the ALWAYS and ** NEVER macros were defined at compile-time. ** - ** The return value is ALWAYS(X). + ** The return value is ALWAYS(X) if X is true, or 0 if X is false. ** ** The recommended test is X==2. If the return value is 2, that means ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the @@ -3739,7 +3902,7 @@ int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_ALWAYS: { int x = va_arg(ap,int); - rc = ALWAYS(x); + rc = x ? ALWAYS(x) : 0; break; } @@ -3788,40 +3951,6 @@ int sqlite3_test_control(int op, ...){ break; } -#ifdef SQLITE_N_KEYWORD - /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord) - ** - ** If zWord is a keyword recognized by the parser, then return the - ** number of keywords. Or if zWord is not a keyword, return 0. - ** - ** This test feature is only available in the amalgamation since - ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite - ** is built using separate source files. - */ - case SQLITE_TESTCTRL_ISKEYWORD: { - const char *zWord = va_arg(ap, const char*); - int n = sqlite3Strlen30(zWord); - rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0; - break; - } -#endif - - /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); - ** - ** Pass pFree into sqlite3ScratchFree(). - ** If sz>0 then allocate a scratch buffer into pNew. - */ - case SQLITE_TESTCTRL_SCRATCHMALLOC: { - void *pFree, **ppNew; - int sz; - sz = va_arg(ap, int); - ppNew = va_arg(ap, void**); - pFree = va_arg(ap, void*); - if( sz ) *ppNew = sqlite3ScratchMalloc(sz); - sqlite3ScratchFree(pFree); - break; - } - /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); ** ** If parameter onoff is non-zero, configure the wrappers so that all @@ -3863,7 +3992,8 @@ int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_VDBE_COVERAGE: { #ifdef SQLITE_VDBE_COVERAGE - typedef void (*branch_callback)(void*,int,u8,u8); + typedef void (*branch_callback)(void*,unsigned int, + unsigned char,unsigned char); sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); #endif @@ -3915,6 +4045,22 @@ int sqlite3_test_control(int op, ...){ sqlite3_mutex_leave(db->mutex); break; } + +#if defined(YYCOVERAGE) + /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out) + ** + ** This test control (only available when SQLite is compiled with + ** -DYYCOVERAGE) writes a report onto "out" that shows all + ** state/lookahead combinations in the parser state machine + ** which are never exercised. If any state is missed, make the + ** return code SQLITE_ERROR. + */ + case SQLITE_TESTCTRL_PARSER_COVERAGE: { + FILE *out = va_arg(ap, FILE*); + if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR; + break; + } +#endif /* defined(YYCOVERAGE) */ } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -3963,7 +4109,7 @@ sqlite3_int64 sqlite3_uri_int64( ){ const char *z = sqlite3_uri_parameter(zFilename, zParam); sqlite3_int64 v; - if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ + if( z && sqlite3DecOrHexToI64(z, &v)==0 ){ bDflt = v; } return bDflt; @@ -4034,7 +4180,7 @@ int sqlite3_snapshot_get( if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( 0==sqlite3BtreeIsInTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); } @@ -4069,11 +4215,29 @@ int sqlite3_snapshot_open( iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot); + if( sqlite3BtreeIsInTrans(pBt)==0 ){ + Pager *pPager = sqlite3BtreePager(pBt); + int bUnlock = 0; + if( sqlite3BtreeIsInReadTrans(pBt) ){ + if( db->nVdbeActive==0 ){ + rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); + if( rc==SQLITE_OK ){ + bUnlock = 1; + rc = sqlite3BtreeCommit(pBt); + } + } + }else{ + rc = SQLITE_OK; + } if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); - sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0); + rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot); + } + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); + } + if( bUnlock ){ + sqlite3PagerSnapshotUnlock(pPager); } } } @@ -4104,7 +4268,7 @@ int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); sqlite3BtreeCommit(pBt); diff --git a/src/malloc.c b/src/malloc.c index 5eb65bf623..d7f9df5efc 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -32,14 +32,6 @@ int sqlite3_release_memory(int n){ #endif } -/* -** An instance of the following object records the location of -** each unused scratch buffer. -*/ -typedef struct ScratchFreeslot { - struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ -} ScratchFreeslot; - /* ** State information local to the memory allocation subsystem. */ @@ -47,22 +39,12 @@ static SQLITE_WSD struct Mem0Global { sqlite3_mutex *mutex; /* Mutex to serialize access */ sqlite3_int64 alarmThreshold; /* The soft heap limit */ - /* - ** Pointers to the end of sqlite3GlobalConfig.pScratch memory - ** (so that a range test can be used to determine if an allocation - ** being freed came from pScratch) and a pointer to the list of - ** unused scratch allocations. - */ - void *pScratchEnd; - ScratchFreeslot *pScratchFree; - u32 nScratchFree; - /* ** True if heap is nearly "full" where "full" is defined by the ** sqlite3_soft_heap_limit() setting. */ int nearlyFull; -} mem0 = { 0, 0, 0, 0, 0, 0 }; +} mem0 = { 0, 0, 0 }; #define mem0 GLOBAL(struct Mem0Global, mem0) @@ -132,28 +114,6 @@ int sqlite3MallocInit(void){ } memset(&mem0, 0, sizeof(mem0)); mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); - if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 - && sqlite3GlobalConfig.nScratch>0 ){ - int i, n, sz; - ScratchFreeslot *pSlot; - sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); - sqlite3GlobalConfig.szScratch = sz; - pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; - n = sqlite3GlobalConfig.nScratch; - mem0.pScratchFree = pSlot; - mem0.nScratchFree = n; - for(i=0; ipNext = (ScratchFreeslot*)(sz+(char*)pSlot); - pSlot = pSlot->pNext; - } - pSlot->pNext = 0; - mem0.pScratchEnd = (void*)&pSlot[1]; - }else{ - mem0.pScratchEnd = 0; - sqlite3GlobalConfig.pScratch = 0; - sqlite3GlobalConfig.szScratch = 0; - sqlite3GlobalConfig.nScratch = 0; - } if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 || sqlite3GlobalConfig.nPage<=0 ){ sqlite3GlobalConfig.pPage = 0; @@ -304,105 +264,6 @@ void *sqlite3_malloc64(sqlite3_uint64 n){ return sqlite3Malloc(n); } -/* -** Each thread may only have a single outstanding allocation from -** xScratchMalloc(). We verify this constraint in the single-threaded -** case by setting scratchAllocOut to 1 when an allocation -** is outstanding clearing it when the allocation is freed. -*/ -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) -static int scratchAllocOut = 0; -#endif - - -/* -** Allocate memory that is to be used and released right away. -** This routine is similar to alloca() in that it is not intended -** for situations where the memory might be held long-term. This -** routine is intended to get memory to old large transient data -** structures that would not normally fit on the stack of an -** embedded processor. -*/ -void *sqlite3ScratchMalloc(int n){ - void *p; - assert( n>0 ); - - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n); - if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ - p = mem0.pScratchFree; - mem0.pScratchFree = mem0.pScratchFree->pNext; - mem0.nScratchFree--; - sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); - sqlite3_mutex_leave(mem0.mutex); - }else{ - sqlite3_mutex_leave(mem0.mutex); - p = sqlite3Malloc(n); - if( sqlite3GlobalConfig.bMemstat && p ){ - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); - sqlite3_mutex_leave(mem0.mutex); - } - sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); - } - assert( sqlite3_mutex_notheld(mem0.mutex) ); - - -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch - ** buffers per thread. - ** - ** This can only be checked in single-threaded mode. - */ - assert( scratchAllocOut==0 ); - if( p ) scratchAllocOut++; -#endif - - return p; -} -void sqlite3ScratchFree(void *p){ - if( p ){ - -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* Verify that no more than two scratch allocation per thread - ** is outstanding at one time. (This is only checked in the - ** single-threaded case since checking in the multi-threaded case - ** would be much more complicated.) */ - assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); - scratchAllocOut--; -#endif - - if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){ - /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */ - ScratchFreeslot *pSlot; - pSlot = (ScratchFreeslot*)p; - sqlite3_mutex_enter(mem0.mutex); - pSlot->pNext = mem0.pScratchFree; - mem0.pScratchFree = pSlot; - mem0.nScratchFree++; - assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); - sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1); - sqlite3_mutex_leave(mem0.mutex); - }else{ - /* Release memory back to the heap */ - assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - if( sqlite3GlobalConfig.bMemstat ){ - int iSize = sqlite3MallocSize(p); - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); - sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); - sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); - sqlite3GlobalConfig.m.xFree(p); - sqlite3_mutex_leave(mem0.mutex); - }else{ - sqlite3GlobalConfig.m.xFree(p); - } - } - } -} - /* ** TRUE if p is a lookaside memory allocation from db */ @@ -493,7 +354,6 @@ void sqlite3DbFreeNN(sqlite3 *db, void *p){ #endif pBuf->pNext = db->lookaside.pFree; db->lookaside.pFree = pBuf; - db->lookaside.nOut--; return; } } @@ -654,16 +514,16 @@ void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ assert( db->mallocFailed==0 ); if( n>db->lookaside.sz ){ db->lookaside.anStat[1]++; - }else if( (pBuf = db->lookaside.pFree)==0 ){ - db->lookaside.anStat[2]++; - }else{ + }else if( (pBuf = db->lookaside.pFree)!=0 ){ db->lookaside.pFree = pBuf->pNext; - db->lookaside.nOut++; db->lookaside.anStat[0]++; - if( db->lookaside.nOut>db->lookaside.mxOut ){ - db->lookaside.mxOut = db->lookaside.nOut; - } return (void*)pBuf; + }else if( (pBuf = db->lookaside.pInit)!=0 ){ + db->lookaside.pInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else{ + db->lookaside.anStat[2]++; } }else if( db->mallocFailed ){ return 0; @@ -767,6 +627,19 @@ char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ return zNew; } +/* +** The text between zStart and zEnd represents a phrase within a larger +** SQL statement. Make a copy of this phrase in space obtained form +** sqlite3DbMalloc(). Omit leading and trailing whitespace. +*/ +char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ + int n; + while( sqlite3Isspace(zStart[0]) ) zStart++; + n = (int)(zEnd - zStart); + while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--; + return sqlite3DbStrNDup(db, zStart, n); +} + /* ** Free any prior content in *pz and replace it with a copy of zNew. */ diff --git a/src/memdb.c b/src/memdb.c new file mode 100644 index 0000000000..7723d40525 --- /dev/null +++ b/src/memdb.c @@ -0,0 +1,589 @@ +/* +** 2016-09-07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file implements an in-memory VFS. A database is held as a contiguous +** block of memory. +** +** This file also implements interface sqlite3_serialize() and +** sqlite3_deserialize(). +*/ +#include "sqliteInt.h" +#ifdef SQLITE_ENABLE_DESERIALIZE + +/* +** Forward declaration of objects used by this utility +*/ +typedef struct sqlite3_vfs MemVfs; +typedef struct MemFile MemFile; + +/* Access to a lower-level VFS that (might) implement dynamic loading, +** access to randomness, etc. +*/ +#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) + +/* An open file */ +struct MemFile { + sqlite3_file base; /* IO methods */ + sqlite3_int64 sz; /* Size of the file */ + sqlite3_int64 szMax; /* Space allocated to aData */ + unsigned char *aData; /* content of the file */ + int nMmap; /* Number of memory mapped pages */ + unsigned mFlags; /* Flags */ + int eLock; /* Most recent lock against this file */ +}; + +/* +** Methods for MemFile +*/ +static int memdbClose(sqlite3_file*); +static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); +static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); +static int memdbSync(sqlite3_file*, int flags); +static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int memdbLock(sqlite3_file*, int); +/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ +static int memdbFileControl(sqlite3_file*, int op, void *pArg); +/* static int memdbSectorSize(sqlite3_file*); // not used */ +static int memdbDeviceCharacteristics(sqlite3_file*); +static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); +static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); + +/* +** Methods for MemVfs +*/ +static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */ +static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename); +static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); +static void memdbDlClose(sqlite3_vfs*, void*); +static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int memdbSleep(sqlite3_vfs*, int microseconds); +/* static int memdbCurrentTime(sqlite3_vfs*, double*); */ +static int memdbGetLastError(sqlite3_vfs*, int, char *); +static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static sqlite3_vfs memdb_vfs = { + 2, /* iVersion */ + 0, /* szOsFile (set when registered) */ + 1024, /* mxPathname */ + 0, /* pNext */ + "memdb", /* zName */ + 0, /* pAppData (set when registered) */ + memdbOpen, /* xOpen */ + 0, /* memdbDelete, */ /* xDelete */ + memdbAccess, /* xAccess */ + memdbFullPathname, /* xFullPathname */ + memdbDlOpen, /* xDlOpen */ + memdbDlError, /* xDlError */ + memdbDlSym, /* xDlSym */ + memdbDlClose, /* xDlClose */ + memdbRandomness, /* xRandomness */ + memdbSleep, /* xSleep */ + 0, /* memdbCurrentTime, */ /* xCurrentTime */ + memdbGetLastError, /* xGetLastError */ + memdbCurrentTimeInt64 /* xCurrentTimeInt64 */ +}; + +static const sqlite3_io_methods memdb_io_methods = { + 3, /* iVersion */ + memdbClose, /* xClose */ + memdbRead, /* xRead */ + memdbWrite, /* xWrite */ + memdbTruncate, /* xTruncate */ + memdbSync, /* xSync */ + memdbFileSize, /* xFileSize */ + memdbLock, /* xLock */ + memdbLock, /* xUnlock - same as xLock in this case */ + 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ + memdbFileControl, /* xFileControl */ + 0, /* memdbSectorSize,*/ /* xSectorSize */ + memdbDeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + memdbFetch, /* xFetch */ + memdbUnfetch /* xUnfetch */ +}; + + + +/* +** Close an memdb-file. +** +** The pData pointer is owned by the application, so there is nothing +** to free. +*/ +static int memdbClose(sqlite3_file *pFile){ + MemFile *p = (MemFile *)pFile; + if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData); + return SQLITE_OK; +} + +/* +** Read data from an memdb-file. +*/ +static int memdbRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + MemFile *p = (MemFile *)pFile; + if( iOfst+iAmt>p->sz ){ + memset(zBuf, 0, iAmt); + if( iOfstsz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst); + return SQLITE_IOERR_SHORT_READ; + } + memcpy(zBuf, p->aData+iOfst, iAmt); + return SQLITE_OK; +} + +/* +** Try to enlarge the memory allocation to hold at least sz bytes +*/ +static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){ + unsigned char *pNew; + if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){ + return SQLITE_FULL; + } + pNew = sqlite3_realloc64(p->aData, newSz); + if( pNew==0 ) return SQLITE_NOMEM; + p->aData = pNew; + p->szMax = newSz; + return SQLITE_OK; +} + +/* +** Write data to an memdb-file. +*/ +static int memdbWrite( + sqlite3_file *pFile, + const void *z, + int iAmt, + sqlite_int64 iOfst +){ + MemFile *p = (MemFile *)pFile; + if( iOfst+iAmt>p->sz ){ + int rc; + if( iOfst+iAmt>p->szMax + && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK + ){ + return rc; + } + if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); + p->sz = iOfst+iAmt; + } + memcpy(p->aData+iOfst, z, iAmt); + return SQLITE_OK; +} + +/* +** Truncate an memdb-file. +** +** In rollback mode (which is always the case for memdb, as it does not +** support WAL mode) the truncate() method is only used to reduce +** the size of a file, never to increase the size. +*/ +static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ + MemFile *p = (MemFile *)pFile; + if( NEVER(size>p->sz) ) return SQLITE_FULL; + p->sz = size; + return SQLITE_OK; +} + +/* +** Sync an memdb-file. +*/ +static int memdbSync(sqlite3_file *pFile, int flags){ + return SQLITE_OK; +} + +/* +** Return the current file-size of an memdb-file. +*/ +static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + MemFile *p = (MemFile *)pFile; + *pSize = p->sz; + return SQLITE_OK; +} + +/* +** Lock an memdb-file. +*/ +static int memdbLock(sqlite3_file *pFile, int eLock){ + MemFile *p = (MemFile *)pFile; + p->eLock = eLock; + return SQLITE_OK; +} + +#if 0 /* Never used because memdbAccess() always returns false */ +/* +** Check if another file-handle holds a RESERVED lock on an memdb-file. +*/ +static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + *pResOut = 0; + return SQLITE_OK; +} +#endif + +/* +** File control method. For custom operations on an memdb-file. +*/ +static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ + MemFile *p = (MemFile *)pFile; + int rc = SQLITE_NOTFOUND; + if( op==SQLITE_FCNTL_VFSNAME ){ + *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); + rc = SQLITE_OK; + } + return rc; +} + +#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +/* +** Return the sector-size in bytes for an memdb-file. +*/ +static int memdbSectorSize(sqlite3_file *pFile){ + return 1024; +} +#endif + +/* +** Return the device characteristic flags supported by an memdb-file. +*/ +static int memdbDeviceCharacteristics(sqlite3_file *pFile){ + return SQLITE_IOCAP_ATOMIC | + SQLITE_IOCAP_POWERSAFE_OVERWRITE | + SQLITE_IOCAP_SAFE_APPEND | + SQLITE_IOCAP_SEQUENTIAL; +} + +/* Fetch a page of a memory-mapped file */ +static int memdbFetch( + sqlite3_file *pFile, + sqlite3_int64 iOfst, + int iAmt, + void **pp +){ + MemFile *p = (MemFile *)pFile; + p->nMmap++; + *pp = (void*)(p->aData + iOfst); + return SQLITE_OK; +} + +/* Release a memory-mapped page */ +static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ + MemFile *p = (MemFile *)pFile; + p->nMmap--; + return SQLITE_OK; +} + +/* +** Open an mem file handle. +*/ +static int memdbOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFile, + int flags, + int *pOutFlags +){ + MemFile *p = (MemFile*)pFile; + if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ + return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags); + } + memset(p, 0, sizeof(*p)); + p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE; + assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */ + *pOutFlags = flags | SQLITE_OPEN_MEMORY; + p->base.pMethods = &memdb_io_methods; + return SQLITE_OK; +} + +#if 0 /* Only used to delete rollback journals, master journals, and WAL + ** files, none of which exist in memdb. So this routine is never used */ +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + return SQLITE_IOERR_DELETE; +} +#endif + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +** +** With memdb, no files ever exist on disk. So always return false. +*/ +static int memdbAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + *pResOut = 0; + return SQLITE_OK; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (INST_MAX_PATHNAME+1) bytes. +*/ +static int memdbFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + sqlite3_snprintf(nOut, zOut, "%s", zPath); + return SQLITE_OK; +} + +/* +** Open the dynamic library located at zPath and return a handle. +*/ +static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); +} + +/* +** Populate the buffer zErrMsg (size nByte bytes) with a human readable +** utf-8 string describing the most recent error encountered associated +** with dynamic libraries. +*/ +static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); +} + +/* +** Return a pointer to the symbol zSymbol in the dynamic library pHandle. +*/ +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ + return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); +} + +/* +** Close the dynamic library handle pHandle. +*/ +static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){ + ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); +} + +/* +** Populate the buffer pointed to by zBufOut with nByte bytes of +** random data. +*/ +static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); +} + +/* +** Sleep for nMicro microseconds. Return the number of microseconds +** actually slept. +*/ +static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){ + return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); +} + +#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */ +/* +** Return the current time as a Julian Day number in *pTimeOut. +*/ +static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); +} +#endif + +static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); +} +static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ + return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); +} + +/* +** Translate a database connection pointer and schema name into a +** MemFile pointer. +*/ +static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){ + MemFile *p = 0; + int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); + if( rc ) return 0; + if( p->base.pMethods!=&memdb_io_methods ) return 0; + return p; +} + +/* +** Return the serialization of a database +*/ +unsigned char *sqlite3_serialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which database within the connection */ + sqlite3_int64 *piSize, /* Write size here, if not NULL */ + unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */ +){ + MemFile *p; + int iDb; + Btree *pBt; + sqlite3_int64 sz; + int szPage = 0; + sqlite3_stmt *pStmt = 0; + unsigned char *pOut; + char *zSql; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; + p = memdbFromDbSchema(db, zSchema); + iDb = sqlite3FindDbName(db, zSchema); + if( piSize ) *piSize = -1; + if( iDb<0 ) return 0; + if( p ){ + if( piSize ) *piSize = p->sz; + if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ + pOut = p->aData; + }else{ + pOut = sqlite3_malloc64( p->sz ); + if( pOut ) memcpy(pOut, p->aData, p->sz); + } + return pOut; + } + pBt = db->aDb[iDb].pBt; + if( pBt==0 ) return 0; + szPage = sqlite3BtreeGetPageSize(pBt); + zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); + rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; + sqlite3_free(zSql); + if( rc ) return 0; + rc = sqlite3_step(pStmt); + if( rc!=SQLITE_ROW ){ + pOut = 0; + }else{ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + if( piSize ) *piSize = sz; + if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ + pOut = 0; + }else{ + pOut = sqlite3_malloc64( sz ); + if( pOut ){ + int nPage = sqlite3_column_int(pStmt, 0); + Pager *pPager = sqlite3BtreePager(pBt); + int pgno; + for(pgno=1; pgno<=nPage; pgno++){ + DbPage *pPage = 0; + unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1); + rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0); + if( rc==SQLITE_OK ){ + memcpy(pTo, sqlite3PagerGetData(pPage), szPage); + }else{ + memset(pTo, 0, szPage); + } + sqlite3PagerUnref(pPage); + } + } + } + } + sqlite3_finalize(pStmt); + return pOut; +} + +/* Convert zSchema to a MemDB and initialize its content. +*/ +int sqlite3_deserialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which DB to reopen with the deserialization */ + unsigned char *pData, /* The serialized database content */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ + sqlite3_int64 szBuf, /* Total size of buffer pData[] */ + unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ +){ + MemFile *p; + char *zSql; + sqlite3_stmt *pStmt = 0; + int rc; + int iDb; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( szDb<0 ) return SQLITE_MISUSE_BKPT; + if( szBuf<0 ) return SQLITE_MISUSE_BKPT; +#endif + + sqlite3_mutex_enter(db->mutex); + if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; + iDb = sqlite3FindDbName(db, zSchema); + if( iDb<0 ){ + rc = SQLITE_ERROR; + goto end_deserialize; + } + zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ) goto end_deserialize; + db->init.iDb = (u8)iDb; + db->init.reopenMemdb = 1; + rc = sqlite3_step(pStmt); + db->init.reopenMemdb = 0; + if( rc!=SQLITE_DONE ){ + rc = SQLITE_ERROR; + goto end_deserialize; + } + p = memdbFromDbSchema(db, zSchema); + if( p==0 ){ + rc = SQLITE_ERROR; + }else{ + p->aData = pData; + p->sz = szDb; + p->szMax = szBuf; + p->mFlags = mFlags; + rc = SQLITE_OK; + } + +end_deserialize: + sqlite3_finalize(pStmt); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This routine is called when the extension is loaded. +** Register the new VFS. +*/ +int sqlite3MemdbInit(void){ + sqlite3_vfs *pLower = sqlite3_vfs_find(0); + int sz = pLower->szOsFile; + memdb_vfs.pAppData = pLower; + /* In all known configurations of SQLite, the size of a default + ** sqlite3_file is greater than the size of a memdb sqlite3_file. + ** Should that ever change, remove the following NEVER() */ + if( NEVER(szxMutexHeld(((CheckMutex*)p)->mutex); +} +static int checkMutexNotheld(sqlite3_mutex *p){ + return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex); +} +#endif + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int checkMutexInit(void){ + pGlobalMutexMethods = sqlite3DefaultMutex(); + return SQLITE_OK; +} +static int checkMutexEnd(void){ + pGlobalMutexMethods = 0; + return SQLITE_OK; +} + +/* +** Allocate a mutex. +*/ +static sqlite3_mutex *checkMutexAlloc(int iType){ + static CheckMutex staticMutexes[] = { + {2, 0}, {3, 0}, {4, 0}, {5, 0}, + {6, 0}, {7, 0}, {8, 0}, {9, 0}, + {10, 0}, {11, 0}, {12, 0}, {13, 0} + }; + CheckMutex *p = 0; + + assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 ); + if( iType<2 ){ + p = sqlite3MallocZero(sizeof(CheckMutex)); + if( p==0 ) return 0; + p->iType = iType; + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + if( iType-2>=ArraySize(staticMutexes) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + p = &staticMutexes[iType-2]; + } + + if( p->mutex==0 ){ + p->mutex = pGlobalMutexMethods->xMutexAlloc(iType); + if( p->mutex==0 ){ + if( iType<2 ){ + sqlite3_free(p); + } + p = 0; + } + } + + return (sqlite3_mutex*)p; +} + +/* +** Free a mutex. +*/ +static void checkMutexFree(sqlite3_mutex *p){ + assert( SQLITE_MUTEX_RECURSIVE<2 ); + assert( SQLITE_MUTEX_FAST<2 ); + assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); + +#if SQLITE_ENABLE_API_ARMOR + if( ((CheckMutex*)p)->iType<2 ) +#endif + { + CheckMutex *pCheck = (CheckMutex*)p; + pGlobalMutexMethods->xMutexFree(pCheck->mutex); + sqlite3_free(pCheck); + } +#ifdef SQLITE_ENABLE_API_ARMOR + else{ + (void)SQLITE_MISUSE_BKPT; + } +#endif +} + +/* +** Enter the mutex. +*/ +static void checkMutexEnter(sqlite3_mutex *p){ + CheckMutex *pCheck = (CheckMutex*)p; + if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){ + if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){ + return; + } + sqlite3_log(SQLITE_MISUSE, + "illegal multi-threaded access to database connection" + ); + } + pGlobalMutexMethods->xMutexEnter(pCheck->mutex); +} + +/* +** Enter the mutex (do not block). +*/ +static int checkMutexTry(sqlite3_mutex *p){ + CheckMutex *pCheck = (CheckMutex*)p; + return pGlobalMutexMethods->xMutexTry(pCheck->mutex); +} + +/* +** Leave the mutex. +*/ +static void checkMutexLeave(sqlite3_mutex *p){ + CheckMutex *pCheck = (CheckMutex*)p; + pGlobalMutexMethods->xMutexLeave(pCheck->mutex); +} + +sqlite3_mutex_methods const *multiThreadedCheckMutex(void){ + static const sqlite3_mutex_methods sMutex = { + checkMutexInit, + checkMutexEnd, + checkMutexAlloc, + checkMutexFree, + checkMutexEnter, + checkMutexTry, + checkMutexLeave, +#ifdef SQLITE_DEBUG + checkMutexHeld, + checkMutexNotheld +#else + 0, + 0 +#endif + }; + return &sMutex; +} + +/* +** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as +** one on which there should be no contention. +*/ +void sqlite3MutexWarnOnContention(sqlite3_mutex *p){ + if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){ + CheckMutex *pCheck = (CheckMutex*)p; + assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE ); + pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION; + } +} +#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */ + /* ** Initialize the mutex system. */ @@ -41,7 +228,11 @@ int sqlite3MutexInit(void){ sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; if( sqlite3GlobalConfig.bCoreMutex ){ +#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS + pFrom = multiThreadedCheckMutex(); +#else pFrom = sqlite3DefaultMutex(); +#endif }else{ pFrom = sqlite3NoopMutex(); } diff --git a/src/mutex_unix.c b/src/mutex_unix.c index 55d08c8052..9282d28016 100644 --- a/src/mutex_unix.c +++ b/src/mutex_unix.c @@ -50,11 +50,12 @@ struct sqlite3_mutex { #endif }; #if SQLITE_MUTEX_NREF -#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0} +# define SQLITE3_MUTEX_INITIALIZER(id) \ + {PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0} #elif defined(SQLITE_ENABLE_API_ARMOR) -#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 } +# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id } #else -#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } +#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER } #endif /* @@ -151,18 +152,18 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } */ static sqlite3_mutex *pthreadMutexAlloc(int iType){ static sqlite3_mutex staticMutexes[] = { - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER + SQLITE3_MUTEX_INITIALIZER(2), + SQLITE3_MUTEX_INITIALIZER(3), + SQLITE3_MUTEX_INITIALIZER(4), + SQLITE3_MUTEX_INITIALIZER(5), + SQLITE3_MUTEX_INITIALIZER(6), + SQLITE3_MUTEX_INITIALIZER(7), + SQLITE3_MUTEX_INITIALIZER(8), + SQLITE3_MUTEX_INITIALIZER(9), + SQLITE3_MUTEX_INITIALIZER(10), + SQLITE3_MUTEX_INITIALIZER(11), + SQLITE3_MUTEX_INITIALIZER(12), + SQLITE3_MUTEX_INITIALIZER(13) }; sqlite3_mutex *p; switch( iType ){ @@ -180,6 +181,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&p->mutex, &recursiveAttr); pthread_mutexattr_destroy(&recursiveAttr); +#endif +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + p->id = SQLITE_MUTEX_RECURSIVE; #endif } break; @@ -188,6 +192,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ p = sqlite3MallocZero( sizeof(*p) ); if( p ){ pthread_mutex_init(&p->mutex, 0); +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + p->id = SQLITE_MUTEX_FAST; +#endif } break; } @@ -203,7 +210,7 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ } } #if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) - if( p ) p->id = iType; + assert( p==0 || p->id==iType ); #endif return p; } diff --git a/src/mutex_w32.c b/src/mutex_w32.c index 9da93cf319..8a8ae289ba 100644 --- a/src/mutex_w32.c +++ b/src/mutex_w32.c @@ -40,7 +40,7 @@ struct sqlite3_mutex { #ifdef SQLITE_DEBUG volatile int nRef; /* Number of enterances */ volatile DWORD owner; /* Thread holding this mutex */ - volatile int trace; /* True to trace changes */ + volatile LONG trace; /* True to trace changes */ #endif }; @@ -52,10 +52,10 @@ struct sqlite3_mutex { #define SQLITE_W32_MUTEX_INITIALIZER { 0 } #ifdef SQLITE_DEBUG -#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ +#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \ 0L, (DWORD)0, 0 } #else -#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } +#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id } #endif #ifdef SQLITE_DEBUG @@ -98,18 +98,18 @@ void sqlite3MemoryBarrier(void){ ** Initialize and deinitialize the mutex subsystem. */ static sqlite3_mutex winMutex_staticMutexes[] = { - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER + SQLITE3_MUTEX_INITIALIZER(2), + SQLITE3_MUTEX_INITIALIZER(3), + SQLITE3_MUTEX_INITIALIZER(4), + SQLITE3_MUTEX_INITIALIZER(5), + SQLITE3_MUTEX_INITIALIZER(6), + SQLITE3_MUTEX_INITIALIZER(7), + SQLITE3_MUTEX_INITIALIZER(8), + SQLITE3_MUTEX_INITIALIZER(9), + SQLITE3_MUTEX_INITIALIZER(10), + SQLITE3_MUTEX_INITIALIZER(11), + SQLITE3_MUTEX_INITIALIZER(12), + SQLITE3_MUTEX_INITIALIZER(13) }; static int winMutex_isInit = 0; @@ -239,15 +239,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){ } #endif p = &winMutex_staticMutexes[iType-2]; - p->id = iType; #ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC - p->trace = 1; + InterlockedCompareExchange(&p->trace, 1, 0); #endif #endif break; } } + assert( p==0 || p->id==iType ); return p; } diff --git a/src/os.c b/src/os.c index 5cf0014794..54b7fcfb29 100644 --- a/src/os.c +++ b/src/os.c @@ -98,7 +98,7 @@ int sqlite3OsTruncate(sqlite3_file *id, i64 size){ } int sqlite3OsSync(sqlite3_file *id, int flags){ DO_OS_MALLOC_TEST(id); - return id->pMethods->xSync(id, flags); + return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK; } int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ DO_OS_MALLOC_TEST(id); @@ -125,8 +125,11 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ ** routine has no return value since the return value would be meaningless. */ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ + if( id->pMethods==0 ) return SQLITE_NOTFOUND; #ifdef SQLITE_TEST - if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){ + if( op!=SQLITE_FCNTL_COMMIT_PHASETWO + && op!=SQLITE_FCNTL_LOCK_TIMEOUT + ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding ** transaction has been committed. Injecting a fault at this point @@ -143,7 +146,7 @@ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ return id->pMethods->xFileControl(id, op, pArg); } void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ - (void)id->pMethods->xFileControl(id, op, pArg); + if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg); } int sqlite3OsSectorSize(sqlite3_file *id){ @@ -153,6 +156,7 @@ int sqlite3OsSectorSize(sqlite3_file *id){ int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ return id->pMethods->xDeviceCharacteristics(id); } +#ifndef SQLITE_OMIT_WAL int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ return id->pMethods->xShmLock(id, offset, n, flags); } @@ -172,6 +176,7 @@ int sqlite3OsShmMap( DO_OS_MALLOC_TEST(id); return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); } +#endif /* SQLITE_OMIT_WAL */ #if SQLITE_MAX_MMAP_SIZE>0 /* The real implementation of xFetch and xUnfetch */ @@ -405,9 +410,12 @@ int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ ** Unregister a VFS so that it is no longer accessible. */ int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + MUTEX_LOGIC(sqlite3_mutex *mutex;) +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; #endif + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); sqlite3_mutex_leave(mutex); diff --git a/src/os.h b/src/os.h index 947f88b36e..f841d6bab1 100644 --- a/src/os.h +++ b/src/os.h @@ -174,10 +174,12 @@ void sqlite3OsFileControlHint(sqlite3_file*,int,void*); #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 int sqlite3OsSectorSize(sqlite3_file *id); int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +#ifndef SQLITE_OMIT_WAL int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); int sqlite3OsShmLock(sqlite3_file *id, int, int, int); void sqlite3OsShmBarrier(sqlite3_file *id); int sqlite3OsShmUnmap(sqlite3_file *id, int); +#endif /* SQLITE_OMIT_WAL */ int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); int sqlite3OsUnfetch(sqlite3_file *, i64, void *); diff --git a/src/os_unix.c b/src/os_unix.c index d1ebd81f68..55f220ea96 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -136,12 +136,10 @@ #define SQLITE_FSFLAGS_IS_MSDOS 0x1 /* -** If we are to be thread-safe, include the pthreads header and define -** the SQLITE_UNIX_THREADS macro. +** If we are to be thread-safe, include the pthreads header. */ #if SQLITE_THREADSAFE # include -# define SQLITE_UNIX_THREADS 1 #endif /* @@ -210,7 +208,7 @@ struct unixFile { unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ - UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ + UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ @@ -229,6 +227,9 @@ struct unixFile { #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + unsigned iBusyTimeout; /* Wait this many millisec on locks */ +#endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ #endif @@ -468,7 +469,11 @@ static struct unix_syscall { #endif #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) +#if defined(HAVE_FCHOWN) { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, +#else + { "geteuid", (sqlite3_syscall_ptr)0, 0 }, +#endif #define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 @@ -483,7 +488,7 @@ static struct unix_syscall { #else { "munmap", (sqlite3_syscall_ptr)0, 0 }, #endif -#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent) +#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent) #if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, @@ -513,7 +518,15 @@ static struct unix_syscall { #endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +# ifdef __ANDROID__ + { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, +# else { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, +# endif +#else + { "ioctl", (sqlite3_syscall_ptr)0, 0 }, +#endif #define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent) }; /* End of the overrideable system calls */ @@ -691,16 +704,30 @@ static int robust_open(const char *z, int f, mode_t m){ ** unixEnterMutex() ** assert( unixMutexHeld() ); ** unixEnterLeave() +** +** To prevent deadlock, the global unixBigLock must must be acquired +** before the unixInodeInfo.pLockMutex mutex, if both are held. It is +** OK to get the pLockMutex without holding unixBigLock first, but if +** that happens, the unixBigLock mutex must not be acquired until after +** pLockMutex is released. +** +** OK: enter(unixBigLock), enter(pLockInfo) +** OK: enter(unixBigLock) +** OK: enter(pLockInfo) +** ERROR: enter(pLockInfo), enter(unixBigLock) */ +static sqlite3_mutex *unixBigLock = 0; static void unixEnterMutex(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); + assert( sqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */ + sqlite3_mutex_enter(unixBigLock); } static void unixLeaveMutex(void){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); + assert( sqlite3_mutex_held(unixBigLock) ); + sqlite3_mutex_leave(unixBigLock); } #ifdef SQLITE_DEBUG static int unixMutexHeld(void) { - return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); + return sqlite3_mutex_held(unixBigLock); } #endif @@ -1090,22 +1117,39 @@ struct unixFileId { /* ** An instance of the following structure is allocated for each open -** inode. Or, on LinuxThreads, there is one of these structures for -** each inode opened by each thread. +** inode. ** ** A single inode can have multiple file descriptors, so each unixFile ** structure contains a pointer to an instance of this object and this ** object keeps a count of the number of unixFile pointing to it. +** +** Mutex rules: +** +** (1) Only the pLockMutex mutex must be held in order to read or write +** any of the locking fields: +** nShared, nLock, eFileLock, bProcessLock, pUnused +** +** (2) When nRef>0, then the following fields are unchanging and can +** be read (but not written) without holding any mutex: +** fileId, pLockMutex +** +** (3) With the exceptions above, all the fields may only be read +** or written while holding the global unixBigLock mutex. +** +** Deadlock prevention: The global unixBigLock mutex may not +** be acquired while holding the pLockMutex mutex. If both unixBigLock +** and pLockMutex are needed, then unixBigLock must be acquired first. */ struct unixInodeInfo { struct unixFileId fileId; /* The lookup key */ - int nShared; /* Number of SHARED locks held */ - unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ - unsigned char bProcessLock; /* An exclusive process lock is held */ + sqlite3_mutex *pLockMutex; /* Hold this mutex for... */ + int nShared; /* Number of SHARED locks held */ + int nLock; /* Number of outstanding file locks */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ int nRef; /* Number of pointers to this structure */ unixShmNode *pShmNode; /* Shared memory associated with this inode */ - int nLock; /* Number of outstanding file locks */ - UnixUnusedFd *pUnused; /* Unused file descriptors to close */ unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ unixInodeInfo *pPrev; /* .... doubly linked */ #if SQLITE_ENABLE_LOCKING_STYLE @@ -1119,8 +1163,26 @@ struct unixInodeInfo { /* ** A lists of all unixInodeInfo objects. +** +** Must hold unixBigLock in order to read or write this variable. */ -static unixInodeInfo *inodeList = 0; +static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ + +#ifdef SQLITE_DEBUG +/* +** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not. +** This routine is used only within assert() to help verify correct mutex +** usage. +*/ +int unixFileMutexHeld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_held(pFile->pInode->pLockMutex); +} +int unixFileMutexNotheld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_notheld(pFile->pInode->pLockMutex); +} +#endif /* ** @@ -1226,6 +1288,7 @@ static void closePendingFds(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; UnixUnusedFd *pNext; + assert( unixFileMutexHeld(pFile) ); for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; robust_close(pFile, p->fd, __LINE__); @@ -1237,17 +1300,20 @@ static void closePendingFds(unixFile *pFile){ /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** -** The mutex entered using the unixEnterMutex() function must be held -** when this function is called. +** The global mutex must be held when this routine is called, but the mutex +** on the inode being deleted must NOT be held. */ static void releaseInodeInfo(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; assert( unixMutexHeld() ); + assert( unixFileMutexNotheld(pFile) ); if( ALWAYS(pInode) ){ pInode->nRef--; if( pInode->nRef==0 ){ assert( pInode->pShmNode==0 ); + sqlite3_mutex_enter(pInode->pLockMutex); closePendingFds(pFile); + sqlite3_mutex_leave(pInode->pLockMutex); if( pInode->pPrev ){ assert( pInode->pPrev->pNext==pInode ); pInode->pPrev->pNext = pInode->pNext; @@ -1259,6 +1325,7 @@ static void releaseInodeInfo(unixFile *pFile){ assert( pInode->pNext->pPrev==pInode ); pInode->pNext->pPrev = pInode->pPrev; } + sqlite3_mutex_free(pInode->pLockMutex); sqlite3_free(pInode); } } @@ -1269,8 +1336,7 @@ static void releaseInodeInfo(unixFile *pFile){ ** describes that file descriptor. Create a new one if necessary. The ** return value might be uninitialized if an error occurs. ** -** The mutex entered using the unixEnterMutex() function must be held -** when this function is called. +** The global mutex must held when calling this routine. ** ** Return an appropriate error code. */ @@ -1331,6 +1397,7 @@ static int findInodeInfo( #else fileId.ino = (u64)statbuf.st_ino; #endif + assert( unixMutexHeld() ); pInode = inodeList; while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ pInode = pInode->pNext; @@ -1342,7 +1409,15 @@ static int findInodeInfo( } memset(pInode, 0, sizeof(*pInode)); memcpy(&pInode->fileId, &fileId, sizeof(fileId)); + if( sqlite3GlobalConfig.bCoreMutex ){ + pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pInode->pLockMutex==0 ){ + sqlite3_free(pInode); + return SQLITE_NOMEM_BKPT; + } + } pInode->nRef = 1; + assert( unixMutexHeld() ); pInode->pNext = inodeList; pInode->pPrev = 0; if( inodeList ) inodeList->pPrev = pInode; @@ -1420,7 +1495,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ assert( pFile ); assert( pFile->eFileLock<=SHARED_LOCK ); - unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ @@ -1445,13 +1520,50 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ } #endif - unixLeaveMutex(); + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); *pResOut = reserved; return rc; } +/* +** Set a posix-advisory-lock. +** +** There are two versions of this routine. If compiled with +** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter +** which is a pointer to a unixFile. If the unixFile->iBusyTimeout +** value is set, then it is the number of milliseconds to wait before +** failing the lock. The iBusyTimeout value is always reset back to +** zero on each call. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking +** attempt to set the lock. +*/ +#ifndef SQLITE_ENABLE_SETLK_TIMEOUT +# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x) +#else +static int osSetPosixAdvisoryLock( + int h, /* The file descriptor on which to take the lock */ + struct flock *pLock, /* The description of the lock */ + unixFile *pFile /* Structure holding timeout value */ +){ + int rc = osFcntl(h,F_SETLK,pLock); + while( rc<0 && pFile->iBusyTimeout>0 ){ + /* On systems that support some kind of blocking file lock with a timeout, + ** make appropriate changes here to invoke that blocking file lock. On + ** generic posix, however, there is no such API. So we simply try the + ** lock once every millisecond until either the timeout expires, or until + ** the lock is obtained. */ + usleep(1000); + rc = osFcntl(h,F_SETLK,pLock); + pFile->iBusyTimeout--; + } + return rc; +} +#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ + + /* ** Attempt to set a system-lock on the file pFile. The lock is ** described by pLock. @@ -1474,8 +1586,8 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ static int unixFileLock(unixFile *pFile, struct flock *pLock){ int rc; unixInodeInfo *pInode = pFile->pInode; - assert( unixMutexHeld() ); assert( pInode!=0 ); + assert( sqlite3_mutex_held(pInode->pLockMutex) ); if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ if( pInode->bProcessLock==0 ){ struct flock lock; @@ -1484,7 +1596,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; lock.l_type = F_WRLCK; - rc = osFcntl(pFile->h, F_SETLK, &lock); + rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile); if( rc<0 ) return rc; pInode->bProcessLock = 1; pInode->nLock++; @@ -1492,7 +1604,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ rc = 0; } }else{ - rc = osFcntl(pFile->h, F_SETLK, pLock); + rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); } return rc; } @@ -1594,8 +1706,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. @@ -1738,7 +1850,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ } end_lock: - unixLeaveMutex(); + sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; @@ -1750,11 +1862,12 @@ end_lock: */ static void setPendingFd(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; - UnixUnusedFd *p = pFile->pUnused; + UnixUnusedFd *p = pFile->pPreallocatedUnused; + assert( unixFileMutexHeld(pFile) ); p->pNext = pInode->pUnused; pInode->pUnused = p; pFile->h = -1; - pFile->pUnused = 0; + pFile->pPreallocatedUnused = 0; } /* @@ -1785,8 +1898,8 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); @@ -1912,14 +2025,14 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ */ pInode->nLock--; assert( pInode->nLock>=0 ); - if( pInode->nLock==0 ){ - closePendingFds(pFile); - } + if( pInode->nLock==0 ) closePendingFds(pFile); } end_unlock: - unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } return rc; } @@ -1979,7 +2092,7 @@ static int closeUnixFile(sqlite3_file *id){ #endif OSTRACE(("CLOSE %-3d\n", pFile->h)); OpenCounter(-1); - sqlite3_free(pFile->pUnused); + sqlite3_free(pFile->pPreallocatedUnused); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } @@ -1990,15 +2103,20 @@ static int closeUnixFile(sqlite3_file *id){ static int unixClose(sqlite3_file *id){ int rc = SQLITE_OK; unixFile *pFile = (unixFile *)id; + unixInodeInfo *pInode = pFile->pInode; + + assert( pInode!=0 ); verifyDbFile(pFile); unixUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); unixEnterMutex(); /* unixFile.pInode is always valid here. Otherwise, a different close ** routine (e.g. nolockClose()) would be called instead. */ assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); - if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){ + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file ** descriptor to pInode->pUnused list. It will be automatically closed @@ -2006,6 +2124,7 @@ static int unixClose(sqlite3_file *id){ */ setPendingFd(pFile); } + sqlite3_mutex_leave(pInode->pLockMutex); releaseInodeInfo(pFile); rc = closeUnixFile(id); unixLeaveMutex(); @@ -2316,7 +2435,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + if( (rc & 0xff) == SQLITE_IOERR ){ rc = SQLITE_OK; reserved=1; } @@ -2383,7 +2502,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) { OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + if( (rc & 0xff) == SQLITE_IOERR ){ rc = SQLITE_BUSY; } #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ @@ -2603,6 +2722,7 @@ static int semXClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; semXUnlock(id, NO_LOCK); assert( pFile ); + assert( unixFileMutexNotheld(pFile) ); unixEnterMutex(); releaseInodeInfo(pFile); unixLeaveMutex(); @@ -2717,8 +2837,7 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ *pResOut = 1; return SQLITE_OK; } - unixEnterMutex(); /* Because pFile->pInode is shared across threads */ - + sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; @@ -2742,7 +2861,7 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ } } - unixLeaveMutex(); + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); *pResOut = reserved; @@ -2805,8 +2924,8 @@ static int afpLock(sqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. @@ -2920,7 +3039,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ /* Can't reestablish the shared lock. Sqlite can't deal, this is ** a critical I/O error */ - rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : + rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : SQLITE_IOERR_LOCK; goto afp_end_lock; } @@ -2942,7 +3061,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ } afp_end_lock: - unixLeaveMutex(); + sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; @@ -2974,8 +3093,8 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); @@ -3044,14 +3163,14 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { if( rc==SQLITE_OK ){ pInode->nLock--; assert( pInode->nLock>=0 ); - if( pInode->nLock==0 ){ - closePendingFds(pFile); - } + if( pInode->nLock==0 ) closePendingFds(pFile); } } - unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } return rc; } @@ -3063,14 +3182,20 @@ static int afpClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; assert( id!=0 ); afpUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); unixEnterMutex(); - if( pFile->pInode && pFile->pInode->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pInode->aPending. It will be automatically closed when - ** the last lock is cleared. - */ - setPendingFd(pFile); + if( pFile->pInode ){ + unixInodeInfo *pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + setPendingFd(pFile); + } + sqlite3_mutex_leave(pInode->pLockMutex); } releaseInodeInfo(pFile); sqlite3_free(pFile->lockingContext); @@ -3200,7 +3325,7 @@ static int unixRead( /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 - assert( pFile->pUnused==0 + assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); @@ -3313,7 +3438,7 @@ static int unixWrite( /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 - assert( pFile->pUnused==0 + assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); @@ -3725,7 +3850,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ do{ err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); }while( err==EINTR ); - if( err ) return SQLITE_IOERR_WRITE; + if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE; #else /* If the OS does not have posix_fallocate(), fake it. Write a ** single byte to the last byte in each block that falls entirely @@ -3851,6 +3976,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ *(int*)pArg = fileHasMoved(pFile); return SQLITE_OK; } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + case SQLITE_FCNTL_LOCK_TIMEOUT: { + pFile->iBusyTimeout = *(int*)pArg; + return SQLITE_OK; + } +#endif #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; @@ -3941,7 +4072,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; pFile->deviceCharacteristics = 0; if( fstatvfs(pFile->h, &fsInfo) == -1 ) { - return pFile->sectorSize; + return; } if( !strcmp(fsInfo.f_basetype, "tmp") ) { @@ -4084,21 +4215,22 @@ static int unixGetpagesize(void){ ** ** The following fields are read-only after the object is created: ** -** fid +** hShm ** zFilename ** -** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and +** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and ** unixMutexHeld() is true when reading or writing any other field ** in this structure. */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ - sqlite3_mutex *mutex; /* Mutex to access this object */ + sqlite3_mutex *pShmMutex; /* Mutex to access this object */ char *zFilename; /* Name of the mmapped file */ - int h; /* Open file descriptor */ + int hShm; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ u16 nRegion; /* Size of array apRegion */ u8 isReadonly; /* True if read-only */ + u8 isUnlocked; /* True if no DMS lock held */ char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ @@ -4116,16 +4248,16 @@ struct unixShmNode { ** The following fields are initialized when this object is created and ** are read-only thereafter: ** -** unixShm.pFile +** unixShm.pShmNode ** unixShm.id ** -** All other fields are read/write. The unixShm.pFile->mutex must be held -** while accessing any read/write fields. +** All other fields are read/write. The unixShm.pShmNode->pShmMutex must +** be held while accessing any read/write fields. */ struct unixShm { unixShmNode *pShmNode; /* The underlying unixShmNode object */ unixShm *pNext; /* Next unixShm with the same unixShmNode */ - u8 hasMutex; /* True if holding the unixShmNode mutex */ + u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */ u8 id; /* Id of this connection within its unixShmNode */ u16 sharedMask; /* Mask of shared locks held */ u16 exclMask; /* Mask of exclusive locks held */ @@ -4155,7 +4287,8 @@ static int unixShmSystemLock( /* Access to the unixShmNode object is serialized by the caller */ pShmNode = pFile->pInode->pShmNode; - assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef>0 || unixMutexHeld() ); /* Shared locks never span more than one byte */ assert( n==1 || lockType!=F_RDLCK ); @@ -4163,15 +4296,13 @@ static int unixShmSystemLock( /* Locks are within range */ assert( n>=1 && n<=SQLITE_SHM_NLOCK ); - if( pShmNode->h>=0 ){ + if( pShmNode->hShm>=0 ){ /* Initialize the locking parameters */ - memset(&f, 0, sizeof(f)); f.l_type = lockType; f.l_whence = SEEK_SET; f.l_start = ofst; f.l_len = n; - - rc = osFcntl(pShmNode->h, F_SETLK, &f); + rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; } @@ -4243,24 +4374,82 @@ static void unixShmPurge(unixFile *pFd){ int nShmPerMap = unixShmRegionPerMap(); int i; assert( p->pInode==pFd->pInode ); - sqlite3_mutex_free(p->mutex); + sqlite3_mutex_free(p->pShmMutex); for(i=0; inRegion; i+=nShmPerMap){ - if( p->h>=0 ){ + if( p->hShm>=0 ){ osMunmap(p->apRegion[i], p->szRegion); }else{ sqlite3_free(p->apRegion[i]); } } sqlite3_free(p->apRegion); - if( p->h>=0 ){ - robust_close(pFd, p->h, __LINE__); - p->h = -1; + if( p->hShm>=0 ){ + robust_close(pFd, p->hShm, __LINE__); + p->hShm = -1; } p->pInode->pShmNode = 0; sqlite3_free(p); } } +/* +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to +** take it now. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If the DMS cannot be locked because this is a readonly_shm=1 +** connection and no other process already holds a lock, return +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. +*/ +static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ + struct flock lock; + int rc = SQLITE_OK; + + /* Use F_GETLK to determine the locks other processes are holding + ** on the DMS byte. If it indicates that another process is holding + ** a SHARED lock, then this process may also take a SHARED lock + ** and proceed with opening the *-shm file. + ** + ** Or, if no other process is holding any lock, then this process + ** is the first to open it. In this case take an EXCLUSIVE lock on the + ** DMS byte and truncate the *-shm file to zero bytes in size. Then + ** downgrade to a SHARED lock on the DMS byte. + ** + ** If another process is holding an EXCLUSIVE lock on the DMS byte, + ** return SQLITE_BUSY to the caller (it will try again). An earlier + ** version of this code attempted the SHARED lock at this point. But + ** this introduced a subtle race condition: if the process holding + ** EXCLUSIVE failed just before truncating the *-shm file, then this + ** process might open and use the *-shm file without truncating it. + ** And if the *-shm file has been corrupted by a power failure or + ** system crash, the database itself may also become corrupt. */ + lock.l_whence = SEEK_SET; + lock.l_start = UNIX_SHM_DMS; + lock.l_len = 1; + lock.l_type = F_WRLCK; + if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) { + rc = SQLITE_IOERR_LOCK; + }else if( lock.l_type==F_UNLCK ){ + if( pShmNode->isReadonly ){ + pShmNode->isUnlocked = 1; + rc = SQLITE_READONLY_CANTINIT; + }else{ + rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); + if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 0) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename); + } + } + }else if( lock.l_type==F_WRLCK ){ + rc = SQLITE_BUSY; + } + + if( rc==SQLITE_OK ){ + assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK ); + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); + } + return rc; +} + /* ** Open a shared-memory area associated with open database file pDbFd. ** This particular implementation uses mmapped files. @@ -4299,9 +4488,9 @@ static void unixShmPurge(unixFile *pFd){ static int unixOpenSharedMemory(unixFile *pDbFd){ struct unixShm *p = 0; /* The connection to be opened */ struct unixShmNode *pShmNode; /* The underlying mmapped file */ - int rc; /* Result code */ + int rc = SQLITE_OK; /* Result code */ unixInodeInfo *pInode; /* The inode of fd */ - char *zShmFilename; /* Name of the file used for SHM */ + char *zShm; /* Name of the file used for SHM */ int nShmFilename; /* Size of the SHM filename in bytes */ /* Allocate space for the new unixShm object. */ @@ -4313,6 +4502,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ /* Check to see if a unixShmNode object already exists. Reuse an existing ** one if present. Create a new one if necessary. */ + assert( unixFileMutexNotheld(pDbFd) ); unixEnterMutex(); pInode = pDbFd->pInode; pShmNode = pInode->pShmNode; @@ -4342,57 +4532,47 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ goto shm_open_err; } memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); - zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; + zShm = pShmNode->zFilename = (char*)&pShmNode[1]; #ifdef SQLITE_SHM_DIRECTORY - sqlite3_snprintf(nShmFilename, zShmFilename, + sqlite3_snprintf(nShmFilename, zShm, SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", (u32)sStat.st_ino, (u32)sStat.st_dev); #else - sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); - sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); + sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); + sqlite3FileSuffix3(pDbFd->zPath, zShm); #endif - pShmNode->h = -1; + pShmNode->hShm = -1; pDbFd->pInode->pShmNode = pShmNode; pShmNode->pInode = pDbFd->pInode; if( sqlite3GlobalConfig.bCoreMutex ){ - pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutex==0 ){ + pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->pShmMutex==0 ){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; } } if( pInode->bProcessLock==0 ){ - int openFlags = O_RDWR | O_CREAT; - if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ - openFlags = O_RDONLY; - pShmNode->isReadonly = 1; + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777)); } - pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); - if( pShmNode->h<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); - goto shm_open_err; + if( pShmNode->hShm<0 ){ + pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777)); + if( pShmNode->hShm<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm); + goto shm_open_err; + } + pShmNode->isReadonly = 1; } /* If this process is running as root, make sure that the SHM file ** is owned by the same user that owns the original database. Otherwise, ** the original owner will not be able to connect. */ - robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); - - /* Check to see if another process is holding the dead-man switch. - ** If not, truncate the file to zero length. - */ - rc = SQLITE_OK; - if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ - if( robust_ftruncate(pShmNode->h, 0) ){ - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); - } - } - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; + robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid); + + rc = unixLockSharedMemory(pDbFd, pShmNode); + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; } } @@ -4409,14 +4589,14 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** the cover of the unixEnterMutex() mutex and the pointer from the ** new (struct unixShm) object to the pShmNode has been set. All that is ** left to do is to link the new object into the linked list starting - ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex - ** mutex. + ** at pShmNode->pFirst. This must be done while holding the + ** pShmNode->pShmMutex. */ - sqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); p->pNext = pShmNode->pFirst; pShmNode->pFirst = p; - sqlite3_mutex_leave(pShmNode->mutex); - return SQLITE_OK; + sqlite3_mutex_leave(pShmNode->pShmMutex); + return rc; /* Jump here on any error */ shm_open_err: @@ -4467,11 +4647,16 @@ static int unixShmMap( p = pDbFd->pShm; pShmNode = p->pShmNode; - sqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); + if( pShmNode->isUnlocked ){ + rc = unixLockSharedMemory(pDbFd, pShmNode); + if( rc!=SQLITE_OK ) goto shmpage_out; + pShmNode->isUnlocked = 0; + } assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); assert( pShmNode->pInode==pDbFd->pInode ); - assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); - assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); /* Minimum number of regions required to be mapped. */ nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; @@ -4483,12 +4668,12 @@ static int unixShmMap( pShmNode->szRegion = szRegion; - if( pShmNode->h>=0 ){ + if( pShmNode->hShm>=0 ){ /* The requested region is not mapped into this processes address space. ** Check to see if it has been allocated (i.e. if the wal-index file is ** large enough to contain the requested region). */ - if( osFstat(pShmNode->h, &sStat) ){ + if( osFstat(pShmNode->hShm, &sStat) ){ rc = SQLITE_IOERR_SHMSIZE; goto shmpage_out; } @@ -4516,7 +4701,7 @@ static int unixShmMap( assert( (nByte % pgsz)==0 ); for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){ int x = 0; - if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){ + if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){ const char *zFile = pShmNode->zFilename; rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); goto shmpage_out; @@ -4539,10 +4724,10 @@ static int unixShmMap( int nMap = szRegion*nShmPerMap; int i; void *pMem; - if( pShmNode->h>=0 ){ + if( pShmNode->hShm>=0 ){ pMem = osMmap(0, nMap, pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, - MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion + MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion ); if( pMem==MAP_FAILED ){ rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); @@ -4571,7 +4756,7 @@ shmpage_out: *pp = 0; } if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; - sqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); return rc; } @@ -4605,12 +4790,12 @@ static int unixShmLock( || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); - assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); - assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); mask = (1<<(ofst+n)) - (1<1 || mask==(1<mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); if( flags & SQLITE_SHM_UNLOCK ){ u16 allMask = 0; /* Mask of locks held by siblings */ @@ -4683,7 +4868,7 @@ static int unixShmLock( } } } - sqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); return rc; @@ -4700,6 +4885,9 @@ static void unixShmBarrier( ){ UNUSED_PARAMETER(fd); sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + assert( fd->pMethods->xLock==nolockLock + || unixFileMutexNotheld((unixFile*)fd) + ); unixEnterMutex(); /* Also mutex, for redundancy */ unixLeaveMutex(); } @@ -4730,22 +4918,23 @@ static int unixShmUnmap( /* Remove connection p from the set of connections associated ** with pShmNode */ - sqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} *pp = p->pNext; /* Free the connection p */ sqlite3_free(p); pDbFd->pShm = 0; - sqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too */ + assert( unixFileMutexNotheld(pDbFd) ); unixEnterMutex(); assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ - if( deleteFlag && pShmNode->h>=0 ){ + if( deleteFlag && pShmNode->hShm>=0 ){ osUnlink(pShmNode->zFilename); } unixShmPurge(pDbFd); @@ -5067,7 +5256,7 @@ IOMETHODS( IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ - 3, /* shared memory is disabled */ + 3, /* shared memory and mmap are enabled */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ nolockUnlock, /* xUnlock method */ @@ -5295,17 +5484,6 @@ static int fillInUnixFile( assert( pNew->pInode==NULL ); - /* Usually the path zFilename should not be a relative pathname. The - ** exception is when opening the proxy "conch" file in builds that - ** include the special Apple locking styles. - */ -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE - assert( zFilename==0 || zFilename[0]=='/' - || pVfs->pAppData==(void*)&autolockIoFinder ); -#else - assert( zFilename==0 || zFilename[0]=='/' ); -#endif - /* No locking occurs in temporary files */ assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); @@ -5564,6 +5742,8 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ #if !OS_VXWORKS struct stat sStat; /* Results of stat() call */ + unixEnterMutex(); + /* A stat() call may fail for various reasons. If this happens, it is ** almost certain that an open() call on the same path will also fail. ** For this reason, if an error occurs in the stat() call here, it is @@ -5572,10 +5752,9 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** ** Even if a subsequent open() call does succeed, the consequences of ** not searching for a reusable file descriptor are not dire. */ - if( 0==osStat(zPath, &sStat) ){ + if( inodeList!=0 && 0==osStat(zPath, &sStat) ){ unixInodeInfo *pInode; - unixEnterMutex(); pInode = inodeList; while( pInode && (pInode->fileId.dev!=sStat.st_dev || pInode->fileId.ino!=(u64)sStat.st_ino) ){ @@ -5583,14 +5762,17 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ } if( pInode ){ UnixUnusedFd **pp; + assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); + sqlite3_mutex_enter(pInode->pLockMutex); for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ *pp = pUnused->pNext; } + sqlite3_mutex_leave(pInode->pLockMutex); } - unixLeaveMutex(); } + unixLeaveMutex(); #endif /* if !OS_VXWORKS */ return pUnused; } @@ -5666,16 +5848,11 @@ static int findCreateFileMode( */ nDb = sqlite3Strlen30(zPath) - 1; while( zPath[nDb]!='-' ){ -#ifndef SQLITE_ENABLE_8_3_NAMES - /* In the normal case (8+3 filenames disabled) the journal filename - ** is guaranteed to contain a '-' character. */ - assert( nDb>0 ); - assert( sqlite3Isalnum(zPath[nDb]) ); -#else - /* If 8+3 names are possible, then the journal file might not contain - ** a '-' character. So check for that case and return early. */ + /* In normal operation, the journal file name will always contain + ** a '-' character. However in 8+3 filename mode, or if a corrupt + ** rollback journal specifies a master journal with a goofy name, then + ** the '-' might be missing. */ if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK; -#endif nDb--; } memcpy(zDb, zPath, nDb); @@ -5750,7 +5927,7 @@ static int unixOpen( ** a file-descriptor on the directory too. The first time unixSync() ** is called the directory file descriptor will be fsync()ed and close()d. */ - int syncDir = (isCreate && ( + int isNewJrnl = (isCreate && ( eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_WAL @@ -5797,7 +5974,6 @@ static int unixOpen( randomnessPid = osGetpid(0); sqlite3_randomness(0,0); } - memset(p, 0, sizeof(unixFile)); if( eType==SQLITE_OPEN_MAIN_DB ){ @@ -5811,7 +5987,7 @@ static int unixOpen( return SQLITE_NOMEM_BKPT; } } - p->pUnused = pUnused; + p->pPreallocatedUnused = pUnused; /* Database filenames are double-zero terminated if they are not ** URIs with parameters. Hence, they can always be passed into @@ -5820,7 +5996,7 @@ static int unixOpen( }else if( !zName ){ /* If zName is NULL, the upper layer is requesting a temp file. */ - assert(isDelete && !syncDir); + assert(isDelete && !isNewJrnl); rc = unixGetTempname(pVfs->mxPathname, zTmpname); if( rc!=SQLITE_OK ){ return rc; @@ -5848,24 +6024,31 @@ static int unixOpen( gid_t gid; /* Groupid for the file */ rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); if( rc!=SQLITE_OK ){ - assert( !p->pUnused ); + assert( !p->pPreallocatedUnused ); assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); return rc; } fd = robust_open(zName, openFlags, openMode); OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); assert( !isExclusive || (openFlags & O_CREAT)!=0 ); - if( fd<0 && errno!=EISDIR && isReadWrite ){ - /* Failed to open the file for read/write access. Try read-only. */ - flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); - openFlags &= ~(O_RDWR|O_CREAT); - flags |= SQLITE_OPEN_READONLY; - openFlags |= O_RDONLY; - isReadonly = 1; - fd = robust_open(zName, openFlags, openMode); + if( fd<0 ){ + if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){ + /* If unable to create a journal because the directory is not + ** writable, change the error code to indicate that. */ + rc = SQLITE_READONLY_DIRECTORY; + }else if( errno!=EISDIR && isReadWrite ){ + /* Failed to open the file for read/write access. Try read-only. */ + flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + openFlags &= ~(O_RDWR|O_CREAT); + flags |= SQLITE_OPEN_READONLY; + openFlags |= O_RDONLY; + isReadonly = 1; + fd = robust_open(zName, openFlags, openMode); + } } if( fd<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); + int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); + if( rc==SQLITE_OK ) rc = rc2; goto open_finished; } @@ -5882,9 +6065,9 @@ static int unixOpen( *pOutFlags = flags; } - if( p->pUnused ){ - p->pUnused->fd = fd; - p->pUnused->flags = flags; + if( p->pPreallocatedUnused ){ + p->pPreallocatedUnused->fd = fd; + p->pPreallocatedUnused->flags = flags; } if( isDelete ){ @@ -5925,7 +6108,7 @@ static int unixOpen( if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; noLock = eType!=SQLITE_OPEN_MAIN_DB; if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; - if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; + if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC; if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; #if SQLITE_ENABLE_LOCKING_STYLE @@ -5961,11 +6144,14 @@ static int unixOpen( } #endif + assert( zPath==0 || zPath[0]=='/' + || eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL + ); rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); open_finished: if( rc!=SQLITE_OK ){ - sqlite3_free(p->pUnused); + sqlite3_free(p->pPreallocatedUnused); } return rc; } @@ -6706,7 +6892,7 @@ static int proxyCreateUnixFile( dummyVfs.zName = "dummy"; pUnused->fd = fd; pUnused->flags = openFlags; - pNew->pUnused = pUnused; + pNew->pPreallocatedUnused = pUnused; rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); if( rc==SQLITE_OK ){ @@ -7662,6 +7848,7 @@ int sqlite3_os_init(void){ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ sqlite3_vfs_register(&aVfs[i], i==0); } + unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); return SQLITE_OK; } @@ -7673,6 +7860,7 @@ int sqlite3_os_init(void){ ** This routine is a no-op for unix. */ int sqlite3_os_end(void){ + unixBigLock = 0; return SQLITE_OK; } diff --git a/src/os_win.c b/src/os_win.c index 7045448fe1..2a4b613ff8 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -315,22 +315,6 @@ struct winVfsAppData { # define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) #endif -/* - * The value used with sqlite3_win32_set_directory() to specify that - * the data directory should be changed. - */ -#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE -# define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1) -#endif - -/* - * The value used with sqlite3_win32_set_directory() to specify that - * the temporary directory should be changed. - */ -#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE -# define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2) -#endif - /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the * various Win32 API heap functions instead of our own. @@ -1927,13 +1911,13 @@ char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ } /* -** This function sets the data directory or the temporary directory based on -** the provided arguments. The type argument must be 1 in order to set the -** data directory or 2 in order to set the temporary directory. The zValue -** argument is the name of the directory to use. The return value will be -** SQLITE_OK if successful. +** This function is the same as sqlite3_win32_set_directory (below); however, +** it accepts a UTF-8 string. */ -int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ +int sqlite3_win32_set_directory8( + unsigned long type, /* Identifier for directory being set or reset */ + const char *zValue /* New value for directory being set or reset */ +){ char **ppDirectory = 0; #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); @@ -1949,20 +1933,53 @@ int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ ); assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); if( ppDirectory ){ - char *zValueUtf8 = 0; + char *zCopy = 0; if( zValue && zValue[0] ){ - zValueUtf8 = winUnicodeToUtf8(zValue); - if ( zValueUtf8==0 ){ + zCopy = sqlite3_mprintf("%s", zValue); + if ( zCopy==0 ){ return SQLITE_NOMEM_BKPT; } } sqlite3_free(*ppDirectory); - *ppDirectory = zValueUtf8; + *ppDirectory = zCopy; return SQLITE_OK; } return SQLITE_ERROR; } +/* +** This function is the same as sqlite3_win32_set_directory (below); however, +** it accepts a UTF-16 string. +*/ +int sqlite3_win32_set_directory16( + unsigned long type, /* Identifier for directory being set or reset */ + const void *zValue /* New value for directory being set or reset */ +){ + int rc; + char *zUtf8 = 0; + if( zValue ){ + zUtf8 = sqlite3_win32_unicode_to_utf8(zValue); + if( zUtf8==0 ) return SQLITE_NOMEM_BKPT; + } + rc = sqlite3_win32_set_directory8(type, zUtf8); + if( zUtf8 ) sqlite3_free(zUtf8); + return rc; +} + +/* +** This function sets the data directory or the temporary directory based on +** the provided arguments. The type argument must be 1 in order to set the +** data directory or 2 in order to set the temporary directory. The zValue +** argument is the name of the directory to use. The return value will be +** SQLITE_OK if successful. +*/ +int sqlite3_win32_set_directory( + unsigned long type, /* Identifier for directory being set or reset */ + void *zValue /* New value for directory being set or reset */ +){ + return sqlite3_win32_set_directory16(type, zValue); +} + /* ** The return value of winGetLastErrorMsg ** is zero if the error message fits in the buffer, or non-zero @@ -2887,6 +2904,9 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ winFile *pFile = (winFile*)id; /* File handle object */ int rc = SQLITE_OK; /* Return code for this function */ DWORD lastErrno; +#if SQLITE_MAX_MMAP_SIZE>0 + sqlite3_int64 oldMmapSize; +#endif assert( pFile ); SimulateIOError(return SQLITE_IOERR_TRUNCATE); @@ -2902,6 +2922,15 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; } +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + oldMmapSize = pFile->mmapSize; + }else{ + oldMmapSize = 0; + } + winUnmapfile(pFile); +#endif + /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ if( winSeekFile(pFile, nByte) ){ rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, @@ -2914,12 +2943,12 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ } #if SQLITE_MAX_MMAP_SIZE>0 - /* If the file was truncated to a size smaller than the currently - ** mapped region, reduce the effective mapping size as well. SQLite will - ** use read() and write() to access data beyond this point from now on. - */ - if( pFile->pMapRegion && nBytemmapSize ){ - pFile->mmapSize = nByte; + if( rc==SQLITE_OK && oldMmapSize>0 ){ + if( oldMmapSize>nByte ){ + winMapfile(pFile, -1); + }else{ + winMapfile(pFile, oldMmapSize); + } } #endif @@ -3631,15 +3660,16 @@ static SYSTEM_INFO winSysInfo; ** assert( winShmMutexHeld() ); ** winShmLeaveMutex() */ +static sqlite3_mutex *winBigLock = 0; static void winShmEnterMutex(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); + sqlite3_mutex_enter(winBigLock); } static void winShmLeaveMutex(void){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); + sqlite3_mutex_leave(winBigLock); } #ifndef NDEBUG static int winShmMutexHeld(void) { - return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); + return sqlite3_mutex_held(winBigLock); } #endif @@ -3673,6 +3703,9 @@ struct winShmNode { int szRegion; /* Size of shared-memory regions */ int nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + u8 isUnlocked; /* True if no DMS lock held */ + struct ShmRegion { HANDLE hMap; /* File handle from CreateFileMapping */ void *pMap; @@ -3739,7 +3772,7 @@ static int winShmSystemLock( int rc = 0; /* Result code form Lock/UnlockFileEx() */ /* Access to the winShmNode object is serialized by the caller */ - assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); + assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", pFile->hFile.h, lockType, ofst, nByte)); @@ -3820,6 +3853,37 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ } } +/* +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to +** take it now. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If the DMS cannot be locked because this is a readonly_shm=1 +** connection and no other process already holds a lock, return +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. +*/ +static int winLockSharedMemory(winShmNode *pShmNode){ + int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); + + if( rc==SQLITE_OK ){ + if( pShmNode->isReadonly ){ + pShmNode->isUnlocked = 1; + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + return SQLITE_READONLY_CANTINIT; + }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), + "winLockSharedMemory", pShmNode->zFilename); + } + } + + if( rc==SQLITE_OK ){ + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + } + + return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); +} + /* ** Open the shared-memory area associated with database file pDbFd. ** @@ -3829,9 +3893,9 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ */ static int winOpenSharedMemory(winFile *pDbFd){ struct winShm *p; /* The connection to be opened */ - struct winShmNode *pShmNode = 0; /* The underlying mmapped file */ - int rc; /* Result code */ - struct winShmNode *pNew; /* Newly allocated winShmNode */ + winShmNode *pShmNode = 0; /* The underlying mmapped file */ + int rc = SQLITE_OK; /* Result code */ + winShmNode *pNew; /* Newly allocated winShmNode */ int nName; /* Size of zName in bytes */ assert( pDbFd->pShm==0 ); /* Not previously opened */ @@ -3864,6 +3928,9 @@ static int winOpenSharedMemory(winFile *pDbFd){ if( pShmNode ){ sqlite3_free(pNew); }else{ + int inFlags = SQLITE_OPEN_WAL; + int outFlags = 0; + pShmNode = pNew; pNew = 0; ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; @@ -3878,30 +3945,23 @@ static int winOpenSharedMemory(winFile *pDbFd){ } } - rc = winOpen(pDbFd->pVfs, - pShmNode->zFilename, /* Name of the file (UTF-8) */ - (sqlite3_file*)&pShmNode->hFile, /* File handle here */ - SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, - 0); - if( SQLITE_OK!=rc ){ + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + }else{ + inFlags |= SQLITE_OPEN_READONLY; + } + rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, + (sqlite3_file*)&pShmNode->hFile, + inFlags, &outFlags); + if( rc!=SQLITE_OK ){ + rc = winLogError(rc, osGetLastError(), "winOpenShm", + pShmNode->zFilename); goto shm_open_err; } + if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; - /* Check to see if another process is holding the dead-man switch. - ** If not, truncate the file to zero length. - */ - if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ - rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); - if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), - "winOpenShm", pDbFd->zPath); - } - } - if( rc==SQLITE_OK ){ - winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); - rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; + rc = winLockSharedMemory(pShmNode); + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; } /* Make the new connection a child of the winShmNode */ @@ -3924,7 +3984,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ p->pNext = pShmNode->pFirst; pShmNode->pFirst = p; sqlite3_mutex_leave(pShmNode->mutex); - return SQLITE_OK; + return rc; /* Jump here on any error */ shm_open_err: @@ -4128,6 +4188,8 @@ static int winShmMap( winFile *pDbFd = (winFile*)fd; winShm *pShm = pDbFd->pShm; winShmNode *pShmNode; + DWORD protect = PAGE_READWRITE; + DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; int rc = SQLITE_OK; if( !pShm ){ @@ -4138,6 +4200,11 @@ static int winShmMap( pShmNode = pShm->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); + if( pShmNode->isUnlocked ){ + rc = winLockSharedMemory(pShmNode); + if( rc!=SQLITE_OK ) goto shmpage_out; + pShmNode->isUnlocked = 0; + } assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); if( pShmNode->nRegion<=iRegion ){ @@ -4184,21 +4251,26 @@ static int winShmMap( } pShmNode->aRegion = apNew; + if( pShmNode->isReadonly ){ + protect = PAGE_READONLY; + flags = FILE_MAP_READ; + } + while( pShmNode->nRegion<=iRegion ){ HANDLE hMap = NULL; /* file-mapping handle */ void *pMap = 0; /* Mapped memory region */ #if SQLITE_OS_WINRT hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, - NULL, PAGE_READWRITE, nByte, NULL + NULL, protect, nByte, NULL ); #elif defined(SQLITE_WIN32_HAS_WIDE) hMap = osCreateFileMappingW(pShmNode->hFile.h, - NULL, PAGE_READWRITE, 0, nByte, NULL + NULL, protect, 0, nByte, NULL ); #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA hMap = osCreateFileMappingA(pShmNode->hFile.h, - NULL, PAGE_READWRITE, 0, nByte, NULL + NULL, protect, 0, nByte, NULL ); #endif OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", @@ -4208,11 +4280,11 @@ static int winShmMap( int iOffset = pShmNode->nRegion*szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; #if SQLITE_OS_WINRT - pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + pMap = osMapViewOfFileFromApp(hMap, flags, iOffset - iOffsetShift, szRegion + iOffsetShift ); #else - pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + pMap = osMapViewOfFile(hMap, flags, 0, iOffset - iOffsetShift, szRegion + iOffsetShift ); #endif @@ -4243,6 +4315,7 @@ shmpage_out: }else{ *pp = 0; } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; sqlite3_mutex_leave(pShmNode->mutex); return rc; } @@ -4879,6 +4952,14 @@ static int winIsDir(const void *zConverted){ return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); } +/* forward reference */ +static int winAccess( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pResOut /* OUT: Result */ +); + /* ** Open a file. */ @@ -5055,37 +5136,58 @@ static int winOpen( extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; extendedParameters.lpSecurityAttributes = NULL; extendedParameters.hTemplateFile = NULL; - while( (h = osCreateFile2((LPCWSTR)zConverted, - dwDesiredAccess, - dwShareMode, - dwCreationDisposition, - &extendedParameters))==INVALID_HANDLE_VALUE && - winRetryIoerr(&cnt, &lastErrno) ){ - /* Noop */ - } + do{ + h = osCreateFile2((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, + dwCreationDisposition, + &extendedParameters); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2, isRO = 0; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); #else - while( (h = osCreateFileW((LPCWSTR)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - winRetryIoerr(&cnt, &lastErrno) ){ - /* Noop */ - } + do{ + h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2, isRO = 0; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); #endif } #ifdef SQLITE_WIN32_HAS_ANSI else{ - while( (h = osCreateFileA((LPCSTR)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - winRetryIoerr(&cnt, &lastErrno) ){ - /* Noop */ - } + do{ + h = osCreateFileA((LPCSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2, isRO = 0; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); } #endif winLogIoerr(cnt, __LINE__); @@ -5094,8 +5196,6 @@ static int winOpen( dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); if( h==INVALID_HANDLE_VALUE ){ - pFile->lastErrno = lastErrno; - winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); sqlite3_free(zConverted); sqlite3_free(zTmpname); if( isReadWrite && !isExclusive ){ @@ -5104,6 +5204,8 @@ static int winOpen( ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); }else{ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); return SQLITE_CANTOPEN_BKPT; } } @@ -5696,9 +5798,6 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ EntropyGatherer e; UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); -#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE - rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ -#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ e.a = (unsigned char*)zBuf; e.na = nBuf; e.nXor = 0; @@ -5993,6 +6092,10 @@ int sqlite3_os_init(void){ sqlite3_vfs_register(&winLongPathNolockVfs, 0); #endif +#ifndef SQLITE_OMIT_WAL + winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + return SQLITE_OK; } @@ -6003,6 +6106,11 @@ int sqlite3_os_end(void){ sleepObj = NULL; } #endif + +#ifndef SQLITE_OMIT_WAL + winBigLock = 0; +#endif + return SQLITE_OK; } diff --git a/src/pager.c b/src/pager.c index 51661044d2..92d32fd275 100644 --- a/src/pager.c +++ b/src/pager.c @@ -128,8 +128,8 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file ** struct as its argument. */ -#define PAGERID(p) ((int)(p->fd)) -#define FILEHANDLEID(fd) ((int)fd) +#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd)) +#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd)) /* ** The Pager.eState variable stores the current 'state' of a pager. A @@ -616,6 +616,18 @@ struct PagerSavepoint { ** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode ** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX ** sub-codes. +** +** syncFlags, walSyncFlags +** +** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). +** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode +** and contains the flags used to sync the checkpoint operations in the +** lower two bits, and sync flags used for transaction commits in the WAL +** file in bits 0x04 and 0x08. In other words, to get the correct sync flags +** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct +** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note +** that with synchronous=NORMAL in WAL mode, transaction commit is not synced +** meaning that the 0x04 and 0x08 bits are both zero. */ struct Pager { sqlite3_vfs *pVfs; /* OS functions to use for IO */ @@ -625,9 +637,8 @@ struct Pager { u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 extraSync; /* sync directory after journal delete */ - u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ - u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ + u8 walSyncFlags; /* See description above */ u8 tempFile; /* zFilename is a temporary or immutable file */ u8 noLock; /* Do not lock (except in WAL mode) */ u8 readOnly; /* True for a read-only database */ @@ -688,7 +699,7 @@ struct Pager { char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ - int aStat[3]; /* Total cache hits, misses and writes */ + int aStat[4]; /* Total cache hits, misses, writes, spills */ #ifdef SQLITE_TEST int nRead; /* Database pages read */ #endif @@ -716,6 +727,7 @@ struct Pager { #define PAGER_STAT_HIT 0 #define PAGER_STAT_MISS 1 #define PAGER_STAT_WRITE 2 +#define PAGER_STAT_SPILL 3 /* ** The following global variables hold counters used for @@ -985,8 +997,12 @@ static int assert_pager_state(Pager *p){ ** to "print *pPager" in gdb: ** ** (gdb) printf "%s", print_pager_state(pPager) +** +** This routine has external linkage in order to suppress compiler warnings +** about an unused function. It is enclosed within SQLITE_DEBUG and so does +** not appear in normal builds. */ -static char *print_pager_state(Pager *p){ +char *print_pager_state(Pager *p){ static char zRet[1024]; sqlite3_snprintf(1024, zRet, @@ -1197,10 +1213,12 @@ static int jrnlBufferSize(Pager *pPager){ assert( isOpen(pPager->fd) ); dc = sqlite3OsDeviceCharacteristics(pPager->fd); +#else + UNUSED_PARAMETER(pPager); #endif #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE - if( dc&SQLITE_IOCAP_BATCH_ATOMIC ){ + if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){ return -1; } #endif @@ -1304,6 +1322,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ || szJ<16 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) || len>=nMaster + || len>szJ-16 || len==0 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) @@ -1749,7 +1768,6 @@ static void pager_reset(Pager *pPager){ ** Return the pPager->iDataVersion value */ u32 sqlite3PagerDataVersion(Pager *pPager){ - assert( pPager->eState>PAGER_OPEN ); return pPager->iDataVersion; } @@ -2115,7 +2133,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ rc = pager_truncate(pPager, pPager->dbSize); } - if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){ + if( rc==SQLITE_OK && bCommit ){ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } @@ -2795,6 +2813,7 @@ static int pager_playback(Pager *pPager, int isHot){ char *zMaster = 0; /* Name of master journal file if any */ int needPagerReset; /* True to reset page prior to first page rollback */ int nPlayback = 0; /* Total number of pages restored from journal */ + u32 savedPageSize = pPager->pageSize; /* Figure out how many records are in the journal. Abort early if ** the journal is empty. @@ -2924,15 +2943,16 @@ static int pager_playback(Pager *pPager, int isHot){ assert( 0 ); end_playback: + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1); + } /* Following a rollback, the database file should be back in its original ** state prior to the start of the transaction, so invoke the ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the ** assertion that the transaction counter was modified. */ #ifdef SQLITE_DEBUG - if( pPager->fd->pMethods ){ - sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); - } + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); #endif /* If this playback is happening automatically as a result of an IO or @@ -2982,7 +3002,8 @@ end_playback: /* -** Read the content for page pPg out of the database file and into +** Read the content for page pPg out of the database file (or out of +** the WAL if that is where the most recent copy if found) into ** pPg->pData. A shared lock or greater must be held on the database ** file before this function is called. ** @@ -2992,30 +3013,33 @@ end_playback: ** If an IO error occurs, then the IO error is returned to the caller. ** Otherwise, SQLITE_OK is returned. */ -static int readDbPage(PgHdr *pPg, u32 iFrame){ +static int readDbPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ - Pgno pgno = pPg->pgno; /* Page number to read */ int rc = SQLITE_OK; /* Return code */ - int pgsz = pPager->pageSize; /* Number of bytes to read */ + +#ifndef SQLITE_OMIT_WAL + u32 iFrame = 0; /* Frame of WAL containing pgno */ assert( pPager->eState>=PAGER_READER && !MEMDB ); assert( isOpen(pPager->fd) ); -#ifndef SQLITE_OMIT_WAL + if( pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); + if( rc ) return rc; + } if( iFrame ){ - /* Try to pull the page from the write-ahead log. */ - rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); + rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); }else #endif { - i64 iOffset = (pgno-1)*(i64)pPager->pageSize; - rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); + i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; + rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } } - if( pgno==1 ){ + if( pPg->pgno==1 ){ if( rc ){ /* If the read is unsuccessful, set the dbFileVers[] to something ** that will never be a valid file version. dbFileVers[] is a copy @@ -3035,13 +3059,13 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){ memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); } } - CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT); + CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT); PAGER_INCR(sqlite3_pager_readdb_count); PAGER_INCR(pPager->nRead); - IOTRACE(("PGIN %p %d\n", pPager, pgno)); + IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno)); PAGERTRACE(("FETCH %d page %d hash(%08x)\n", - PAGERID(pPager), pgno, pager_pagehash(pPg))); + PAGERID(pPager), pPg->pgno, pager_pagehash(pPg))); return rc; } @@ -3092,11 +3116,7 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){ if( sqlite3PcachePageRefcount(pPg)==1 ){ sqlite3PcacheDrop(pPg); }else{ - u32 iFrame = 0; - rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); - if( rc==SQLITE_OK ){ - rc = readDbPage(pPg, iFrame); - } + rc = readDbPage(pPg); if( rc==SQLITE_OK ){ pPager->xReiniter(pPg); } @@ -3602,20 +3622,17 @@ void sqlite3PagerSetFlags( } if( pPager->noSync ){ pPager->syncFlags = 0; - pPager->ckptSyncFlags = 0; }else if( pgFlags & PAGER_FULLFSYNC ){ pPager->syncFlags = SQLITE_SYNC_FULL; - pPager->ckptSyncFlags = SQLITE_SYNC_FULL; - }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ - pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = SQLITE_SYNC_FULL; }else{ pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } - pPager->walSyncFlags = pPager->syncFlags; + pPager->walSyncFlags = (pPager->syncFlags<<2); if( pPager->fullSync ){ - pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; + pPager->walSyncFlags |= pPager->syncFlags; + } + if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){ + pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2); } if( pgFlags & PAGER_CACHESPILL ){ pPager->doNotSpill &= ~SPILLFLAG_OFF; @@ -3688,20 +3705,18 @@ static int pagerOpentemp( ** retried. If it returns zero, then the SQLITE_BUSY error is ** returned to the caller of the pager API function. */ -void sqlite3PagerSetBusyhandler( +void sqlite3PagerSetBusyHandler( Pager *pPager, /* Pager object */ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ ){ + void **ap; pPager->xBusyHandler = xBusyHandler; pPager->pBusyHandlerArg = pBusyHandlerArg; - - if( isOpen(pPager->fd) ){ - void **ap = (void **)&pPager->xBusyHandler; - assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); - assert( ap[1]==pBusyHandlerArg ); - sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); - } + ap = (void **)&pPager->xBusyHandler; + assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); + assert( ap[1]==pBusyHandlerArg ); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); } /* @@ -4087,6 +4102,30 @@ static void pagerFreeMapHdrs(Pager *pPager){ } } +/* Verify that the database file has not be deleted or renamed out from +** under the pager. Return SQLITE_OK if the database is still where it ought +** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error +** code from sqlite3OsAccess()) if the database has gone missing. +*/ +static int databaseIsUnmoved(Pager *pPager){ + int bHasMoved = 0; + int rc; + + if( pPager->tempFile ) return SQLITE_OK; + if( pPager->dbSize==0 ) return SQLITE_OK; + assert( pPager->zFilename && pPager->zFilename[0] ); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); + if( rc==SQLITE_NOTFOUND ){ + /* If the HAS_MOVED file-control is unimplemented, assume that the file + ** has not been moved. That is the historical behavior of SQLite: prior to + ** version 3.8.3, it never checked */ + rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bHasMoved ){ + rc = SQLITE_READONLY_DBMOVED; + } + return rc; +} + /* ** Shutdown the page cache. Free all memory and close all files. @@ -4103,8 +4142,7 @@ static void pagerFreeMapHdrs(Pager *pPager){ ** to the caller. */ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ - u8 *pTmp = (u8 *)pPager->pTmpSpace; - + u8 *pTmp = (u8*)pPager->pTmpSpace; assert( db || pagerUseWal(pPager)==0 ); assert( assert_pager_state(pPager) ); disable_simulated_io_errors(); @@ -4113,11 +4151,17 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ /* pPager->errCode = 0; */ pPager->exclusiveMode = 0; #ifndef SQLITE_OMIT_WAL - assert( db || pPager->pWal==0 ); - sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, - (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp) - ); - pPager->pWal = 0; + { + u8 *a = 0; + assert( db || pPager->pWal==0 ); + if( db && 0==(db->flags & SQLITE_NoCkptOnClose) + && SQLITE_OK==databaseIsUnmoved(pPager) + ){ + a = pTmp; + } + sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + pPager->pWal = 0; + } #endif pager_reset(pPager); if( MEMDB ){ @@ -4574,6 +4618,7 @@ static int pagerStress(void *p, PgHdr *pPg){ return SQLITE_OK; } + pPager->aStat[PAGER_STAT_SPILL]++; pPg->pDirty = 0; if( pagerUseWal(pPager) ){ /* Write a single frame for this page to the log. */ @@ -4679,6 +4724,11 @@ int sqlite3PagerOpen( int rc = SQLITE_OK; /* Return code */ int tempFile = 0; /* True for temp files (incl. in-memory files) */ int memDb = 0; /* True if this is an in-memory file */ +#ifdef SQLITE_ENABLE_DESERIALIZE + int memJM = 0; /* Memory journal mode */ +#else +# define memJM 0 +#endif int readOnly = 0; /* True if this is a read-only file */ int journalFileSize; /* Bytes to allocate for each journal fd */ char *zPathname = 0; /* Full path to database file */ @@ -4806,7 +4856,10 @@ int sqlite3PagerOpen( int fout = 0; /* VFS flags returned by xOpen() */ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); - readOnly = (fout&SQLITE_OPEN_READONLY); +#ifdef SQLITE_ENABLE_DESERIALIZE + memJM = (fout&SQLITE_OPEN_MEMORY)!=0; +#endif + readOnly = (fout&SQLITE_OPEN_READONLY)!=0; /* If the file was successfully opened for read/write access, ** choose a default page size in case we have to create the @@ -4922,13 +4975,11 @@ act_like_temp_file: assert( pPager->extraSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); - assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; pPager->extraSync = 0; pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; - pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ @@ -4939,7 +4990,7 @@ act_like_temp_file: setSectorSize(pPager); if( !useJournal ){ pPager->journalMode = PAGER_JOURNALMODE_OFF; - }else if( memDb ){ + }else if( memDb || memJM ){ pPager->journalMode = PAGER_JOURNALMODE_MEMORY; } /* pPager->xBusyHandler = 0; */ @@ -4954,30 +5005,6 @@ act_like_temp_file: } -/* Verify that the database file has not be deleted or renamed out from -** under the pager. Return SQLITE_OK if the database is still were it ought -** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error -** code from sqlite3OsAccess()) if the database has gone missing. -*/ -static int databaseIsUnmoved(Pager *pPager){ - int bHasMoved = 0; - int rc; - - if( pPager->tempFile ) return SQLITE_OK; - if( pPager->dbSize==0 ) return SQLITE_OK; - assert( pPager->zFilename && pPager->zFilename[0] ); - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); - if( rc==SQLITE_NOTFOUND ){ - /* If the HAS_MOVED file-control is unimplemented, assume that the file - ** has not been moved. That is the historical behavior of SQLite: prior to - ** version 3.8.3, it never checked */ - rc = SQLITE_OK; - }else if( rc==SQLITE_OK && bHasMoved ){ - rc = SQLITE_READONLY_DBMOVED; - } - return rc; -} - /* ** This function is called after transitioning from PAGER_UNLOCK to @@ -5348,7 +5375,8 @@ int sqlite3PagerSharedLock(Pager *pPager){ ** nothing to rollback, so this routine is a no-op. */ static void pagerUnlockIfUnused(Pager *pPager){ - if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ + if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){ + assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */ pagerUnlockAndRollback(pPager); } } @@ -5489,14 +5517,9 @@ static int getPageNormal( memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ - u32 iFrame = 0; /* Frame to read from WAL file */ - if( pagerUseWal(pPager) ){ - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); - if( rc!=SQLITE_OK ) goto pager_acquire_err; - } assert( pPg->pPager==pPager ); pPager->aStat[PAGER_STAT_MISS]++; - rc = readDbPage(pPg, iFrame); + rc = readDbPage(pPg); if( rc!=SQLITE_OK ){ goto pager_acquire_err; } @@ -5570,7 +5593,7 @@ static int getPageMMap( } if( pPg==0 ){ rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); - }else{ + }else{ sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); } if( pPg ){ @@ -5639,25 +5662,40 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ /* ** Release a page reference. ** -** If the number of references to the page drop to zero, then the -** page is added to the LRU list. When all references to all pages -** are released, a rollback occurs and the lock on the database is -** removed. +** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be +** used if we know that the page being released is not the last page. +** The btree layer always holds page1 open until the end, so these first +** to routines can be used to release any page other than BtShared.pPage1. +** +** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine +** checks the total number of outstanding pages and if the number of +** pages reaches zero it drops the database lock. */ void sqlite3PagerUnrefNotNull(DbPage *pPg){ - Pager *pPager; + TESTONLY( Pager *pPager = pPg->pPager; ) assert( pPg!=0 ); - pPager = pPg->pPager; if( pPg->flags & PGHDR_MMAP ){ + assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */ pagerReleaseMapPage(pPg); }else{ sqlite3PcacheRelease(pPg); } - pagerUnlockIfUnused(pPager); + /* Do not use this routine to release the last reference to page1 */ + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); } void sqlite3PagerUnref(DbPage *pPg){ if( pPg ) sqlite3PagerUnrefNotNull(pPg); } +void sqlite3PagerUnrefPageOne(DbPage *pPg){ + Pager *pPager; + assert( pPg!=0 ); + assert( pPg->pgno==1 ); + assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ + pPager = pPg->pPager; + sqlite3PagerResetLockTimeout(pPager); + sqlite3PcacheRelease(pPg); + pagerUnlockIfUnused(pPager); +} /* ** This function is called at the start of every write transaction. @@ -6250,12 +6288,9 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ */ int sqlite3PagerSync(Pager *pPager, const char *zMaster){ int rc = SQLITE_OK; - - if( isOpen(pPager->fd) ){ - void *pArg = (void*)zMaster; - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); - if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; - } + void *pArg = (void*)zMaster; + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; if( rc==SQLITE_OK && !pPager->noSync ){ assert( !MEMDB ); rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); @@ -6350,9 +6385,10 @@ int sqlite3PagerCommitPhaseOne( ** backup in progress needs to be restarted. */ sqlite3BackupRestart(pPager->pBackup); }else{ + PgHdr *pList; if( pagerUseWal(pPager) ){ - PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); PgHdr *pPageOne = 0; + pList = sqlite3PcacheDirtyList(pPager->pPCache); if( pList==0 ){ /* Must have at least one page for the WAL commit flag. ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ @@ -6373,14 +6409,14 @@ int sqlite3PagerCommitPhaseOne( ** should be used. No rollback journal is created if batch-atomic-write ** is enabled. */ - sqlite3_file *fd = pPager->fd; #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE - const int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ + sqlite3_file *fd = pPager->fd; + int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) && !pPager->noSync && sqlite3JournalIsInMemory(pPager->jfd); #else -# define bBatch 0 +# define bBatch 0 #endif #ifdef SQLITE_ENABLE_ATOMIC_WRITE @@ -6432,15 +6468,16 @@ int sqlite3PagerCommitPhaseOne( } } } -#else +#else /* SQLITE_ENABLE_ATOMIC_WRITE */ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( zMaster ){ rc = sqlite3JournalCreate(pPager->jfd); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + assert( bBatch==0 ); } #endif rc = pager_incr_changecounter(pPager, 0); -#endif +#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ if( rc!=SQLITE_OK ) goto commit_phase_one_exit; /* Write the master journal name into the journal file. If a master @@ -6464,23 +6501,36 @@ int sqlite3PagerCommitPhaseOne( rc = syncJournal(pPager, 0); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + pList = sqlite3PcacheDirtyList(pPager->pPCache); +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( bBatch ){ - /* The pager is now in DBMOD state. But regardless of what happens - ** next, attempting to play the journal back into the database would - ** be unsafe. Close it now to make sure that does not happen. */ - sqlite3OsClose(pPager->jfd); rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - } - rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); - if( bBatch ){ if( rc==SQLITE_OK ){ - rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); + rc = pager_write_pagelist(pPager, pList); + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); + } + if( rc!=SQLITE_OK ){ + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); + } + } + + if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ){ + sqlite3OsClose(pPager->jfd); + goto commit_phase_one_exit; + } + bBatch = 0; }else{ - sqlite3OsFileControl(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); + sqlite3OsClose(pPager->jfd); } } +#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + if( bBatch==0 ){ + rc = pager_write_pagelist(pPager, pList); + } if( rc!=SQLITE_OK ){ assert( rc!=SQLITE_IOERR_BLOCKED ); goto commit_phase_one_exit; @@ -6701,8 +6751,12 @@ int *sqlite3PagerStats(Pager *pPager){ #endif /* -** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or -** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the +** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE, +** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation +** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because +** it was added later. +** +** Before returning, *pnVal is incremented by the ** current cache hit or miss count, according to the value of eStat. If the ** reset parameter is non-zero, the cache hit or miss count is zeroed before ** returning. @@ -6712,15 +6766,18 @@ void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ assert( eStat==SQLITE_DBSTATUS_CACHE_HIT || eStat==SQLITE_DBSTATUS_CACHE_MISS || eStat==SQLITE_DBSTATUS_CACHE_WRITE + || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1 ); assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS ); assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE ); - assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 ); + assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 + && PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 ); - *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT]; + eStat -= SQLITE_DBSTATUS_CACHE_HIT; + *pnVal += pPager->aStat[eStat]; if( reset ){ - pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0; + pPager->aStat[eStat] = 0; } } @@ -6924,6 +6981,16 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){ return pPager->fd; } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +/* +** Reset the lock timeout for pager. +*/ +void sqlite3PagerResetLockTimeout(Pager *pPager){ + int x = 0; + sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x); +} +#endif + /* ** Return the file handle for the journal file (if it exists). ** This will be either the rollback journal or the WAL file. @@ -7215,13 +7282,6 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){ int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ u8 eOld = pPager->journalMode; /* Prior journalmode */ -#ifdef SQLITE_DEBUG - /* The print_pager_state() routine is intended to be used by the debugger - ** only. We invoke it once here to suppress a compiler warning. */ - print_pager_state(pPager); -#endif - - /* The eMode parameter is always valid */ assert( eMode==PAGER_JOURNALMODE_DELETE || eMode==PAGER_JOURNALMODE_TRUNCATE @@ -7381,9 +7441,10 @@ int sqlite3PagerCheckpoint( rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), pPager->pBusyHandlerArg, - pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, + pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, pnLog, pnCkpt ); + sqlite3PagerResetLockTimeout(pPager); } return rc; } @@ -7538,7 +7599,7 @@ int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ if( rc==SQLITE_OK && pPager->pWal ){ rc = pagerExclusiveLock(pPager); if( rc==SQLITE_OK ){ - rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, + rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize, (u8*)pPager->pTmpSpace); pPager->pWal = 0; pagerFixMaplimit(pPager); @@ -7589,6 +7650,38 @@ int sqlite3PagerSnapshotRecover(Pager *pPager){ } return rc; } + +/* +** The caller currently has a read transaction open on the database. +** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise, +** this function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){ + int rc; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3PagerSnapshotCheck(). +*/ +void sqlite3PagerSnapshotUnlock(Pager *pPager){ + assert( pPager->pWal ); + return sqlite3WalSnapshotUnlock(pPager->pWal); +} + #endif /* SQLITE_ENABLE_SNAPSHOT */ #endif /* !SQLITE_OMIT_WAL */ diff --git a/src/pager.h b/src/pager.h index 585ef29497..5b07a226b8 100644 --- a/src/pager.h +++ b/src/pager.h @@ -126,7 +126,7 @@ int sqlite3PagerClose(Pager *pPager, sqlite3*); int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ -void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); +void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); int sqlite3PagerSetPagesize(Pager*, u32*, int); #ifdef SQLITE_HAS_CODEC void sqlite3PagerAlignReserve(Pager*,Pager*); @@ -151,6 +151,7 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); void sqlite3PagerRef(DbPage*); void sqlite3PagerUnref(DbPage*); void sqlite3PagerUnrefNotNull(DbPage*); +void sqlite3PagerUnrefPageOne(DbPage*); /* Operations on page references. */ int sqlite3PagerWrite(DbPage*); @@ -185,6 +186,8 @@ int sqlite3PagerSharedLock(Pager *pPager); int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); int sqlite3PagerSnapshotRecover(Pager *pPager); + int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot); + void sqlite3PagerSnapshotUnlock(Pager *pPager); # endif #else # define sqlite3PagerUseWal(x,y) 0 @@ -211,6 +214,11 @@ int sqlite3PagerIsMemdb(Pager*); void sqlite3PagerCacheStat(Pager *, int, int, int *); void sqlite3PagerClearCache(Pager*); int sqlite3SectorSize(sqlite3_file *); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +void sqlite3PagerResetLockTimeout(Pager *pPager); +#else +# define sqlite3PagerResetLockTimeout(X) +#endif /* Functions used to truncate the database file. */ void sqlite3PagerTruncateImage(Pager*,Pgno); diff --git a/src/parse.y b/src/parse.y index a8d080eed3..b150c73e1f 100644 --- a/src/parse.y +++ b/src/parse.y @@ -24,15 +24,19 @@ %token_type {Token} %default_type {Token} -// The generated parser function takes a 4th argument as follows: -%extra_argument {Parse *pParse} +// An extra argument to the constructor for the parser, which is available +// to all actions. +%extra_context {Parse *pParse} // This code runs whenever there is a syntax error // %syntax_error { UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ - assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + if( TOKEN.z[0] ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + }else{ + sqlite3ErrorMsg(pParse, "incomplete input"); + } } %stack_overflow { sqlite3ErrorMsg(pParse, "parser stack overflow"); @@ -84,15 +88,6 @@ */ #define YYMALLOCARGTYPE u64 -/* -** An instance of this structure holds information about the -** LIMIT clause of a SELECT statement. -*/ -struct LimitVal { - Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ - Expr *pOffset; /* The OFFSET expression. NULL if there is none */ -}; - /* ** An instance of the following structure describes the event of a ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, @@ -104,6 +99,8 @@ struct LimitVal { */ struct TrigEvent { int a; IdList * b; }; +struct FrameBound { int eType; Expr *pExpr; }; + /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. @@ -120,9 +117,9 @@ input ::= cmdlist. cmdlist ::= cmdlist ecmd. cmdlist ::= ecmd. ecmd ::= SEMI. -ecmd ::= explain cmdx SEMI. -explain ::= . +ecmd ::= cmdx SEMI. %ifndef SQLITE_OMIT_EXPLAIN +ecmd ::= explain cmdx. explain ::= EXPLAIN. { pParse->explain = 1; } explain ::= EXPLAIN QUERY PLAN. { pParse->explain = 2; } %endif SQLITE_OMIT_EXPLAIN @@ -211,13 +208,17 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} // %fallback ID ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW - CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR + CONFLICT DATABASE DEFERRED DESC DETACH DO + EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN - QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW + QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif SQLITE_OMIT_COMPOUND_SELECT +%ifndef SQLITE_OMIT_WINDOWFUNC + CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED +%endif SQLITE_OMIT_WINDOWFUNC REINDEX RENAME CTIME_KW IF . %wildcard ANY. @@ -245,6 +246,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} %left CONCAT. %left COLLATE. %right BITNOT. +%nonassoc ON. // An IDENTIFIER can be a generic identifier, or one of several // keywords. Any non-standard keyword can also be an identifier. @@ -282,26 +284,48 @@ typename(A) ::= typename(A) ids(Y). {A.n=Y.n+(int)(Y.z-A.z);} signed ::= plus_num. signed ::= minus_num. +// The scanpt non-terminal takes a value which is a pointer to the +// input text just past the last token that has been shifted into +// the parser. By surrounding some phrase in the grammar with two +// scanpt non-terminals, we can capture the input text for that phrase. +// For example: +// +// something ::= .... scanpt(A) phrase scanpt(Z). +// +// The text that is parsed as "phrase" is a string starting at A +// and containing (int)(Z-A) characters. There might be some extra +// whitespace on either end of the text, but that can be removed in +// post-processing, if needed. +// +%type scanpt {const char*} +scanpt(A) ::= . { + assert( yyLookahead!=YYNOCODE ); + A = yyLookaheadToken.z; +} + // "carglist" is a list of additional constraints that come after the // column name and column type in a CREATE TABLE statement. // carglist ::= carglist ccons. carglist ::= . ccons ::= CONSTRAINT nm(X). {pParse->constraintName = X;} -ccons ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,&X);} -ccons ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,&X);} -ccons ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,&X);} -ccons ::= DEFAULT MINUS(A) term(X). { - ExprSpan v; - v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, X.pExpr, 0); - v.zStart = A.z; - v.zEnd = X.zEnd; - sqlite3AddDefaultValue(pParse,&v); +ccons ::= DEFAULT scanpt(A) term(X) scanpt(Z). + {sqlite3AddDefaultValue(pParse,X,A,Z);} +ccons ::= DEFAULT LP(A) expr(X) RP(Z). + {sqlite3AddDefaultValue(pParse,X,A.z+1,Z.z);} +ccons ::= DEFAULT PLUS(A) term(X) scanpt(Z). + {sqlite3AddDefaultValue(pParse,X,A.z,Z);} +ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z). { + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0); + sqlite3AddDefaultValue(pParse,p,A.z,Z); } -ccons ::= DEFAULT id(X). { - ExprSpan v; - spanExpr(&v, pParse, TK_STRING, X); - sqlite3AddDefaultValue(pParse,&v); +ccons ::= DEFAULT scanpt id(X). { + Expr *p = tokenExpr(pParse, TK_STRING, X); + if( p ){ + sqlite3ExprIdToTrueFalse(p); + testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) ); + } + sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n); } // In addition to the type name, we also care about the primary key and @@ -313,7 +337,7 @@ ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I). {sqlite3AddPrimaryKey(pParse,0,R,I,Z);} ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} -ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);} +ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);} ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);} @@ -364,7 +388,7 @@ tcons ::= UNIQUE LP sortlist(X) RP onconf(R). {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} tcons ::= CHECK LP expr(E) RP onconf. - {sqlite3AddCheckConstraint(pParse,E.pExpr);} + {sqlite3AddCheckConstraint(pParse,E);} tcons ::= FOREIGN KEY LP eidlist(FA) RP REFERENCES nm(T) eidlist_opt(TA) refargs(R) defer_subclause_opt(D). { sqlite3CreateForeignKey(pParse, FA, &T, TA, R); @@ -448,7 +472,8 @@ cmd ::= select(X). { } } -select(A) ::= with(W) selectnowith(X). { +%ifndef SQLITE_OMIT_CTE +select(A) ::= WITH wqlist(W) selectnowith(X). { Select *p = X; if( p ){ p->pWith = W; @@ -456,7 +481,25 @@ select(A) ::= with(W) selectnowith(X). { }else{ sqlite3WithDelete(pParse->db, W); } - A = p; /*A-overwrites-W*/ + A = p; +} +select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). { + Select *p = X; + if( p ){ + p->pWith = W; + parserDoubleLinkSelect(pParse, p); + }else{ + sqlite3WithDelete(pParse->db, W); + } + A = p; +} +%endif /* SQLITE_OMIT_CTE */ +select(A) ::= selectnowith(X). { + Select *p = X; + if( p ){ + parserDoubleLinkSelect(pParse, p); + } + A = p; /*A-overwrites-X*/ } selectnowith(A) ::= oneselect(A). @@ -470,7 +513,7 @@ selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). { x.n = 0; parserDoubleLinkSelect(pParse, pRhs); pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); - pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)Y; @@ -488,47 +531,36 @@ multiselect_op(A) ::= UNION(OP). {A = @OP; /*A-overwrites-OP*/} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP; /*A-overwrites-OP*/} %endif SQLITE_OMIT_COMPOUND_SELECT -oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y) - groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { -#if SELECTTRACE_ENABLED - Token s = S; /*A-overwrites-S*/ -#endif - A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); -#if SELECTTRACE_ENABLED - /* Populate the Select.zSelName[] string that is used to help with - ** query planner debugging, to differentiate between multiple Select - ** objects in a complex query. - ** - ** If the SELECT keyword is immediately followed by a C-style comment - ** then extract the first few alphanumeric characters from within that - ** comment to be the zSelName value. Otherwise, the label is #N where - ** is an integer that is incremented with each SELECT statement seen. - */ - if( A!=0 ){ - const char *z = s.z+6; - int i; - sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "#%d", - ++pParse->nSelect); - while( z[0]==' ' ) z++; - if( z[0]=='/' && z[1]=='*' ){ - z += 2; - while( z[0]==' ' ) z++; - for(i=0; sqlite3Isalnum(z[i]); i++){} - sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "%.*s", i, z); - } - } -#endif /* SELECTRACE_ENABLED */ + +oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) + groupby_opt(P) having_opt(Q) + orderby_opt(Z) limit_opt(L). { + A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L); } +%ifndef SQLITE_OMIT_WINDOWFUNC +oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) + groupby_opt(P) having_opt(Q) window_clause(R) + orderby_opt(Z) limit_opt(L). { + A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L); + if( A ){ + A->pWinDefn = R; + }else{ + sqlite3WindowListDelete(pParse->db, R); + } +} +%endif + + oneselect(A) ::= values(A). %type values {Select*} %destructor values {sqlite3SelectDelete(pParse->db, $$);} values(A) ::= VALUES LP nexprlist(X) RP. { - A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0); + A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0); } -values(A) ::= values(A) COMMA LP exprlist(Y) RP. { +values(A) ::= values(A) COMMA LP nexprlist(Y) RP. { Select *pRight, *pLeft = A; - pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); + pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; @@ -558,16 +590,16 @@ distinct(A) ::= . {A = 0;} %destructor sclp {sqlite3ExprListDelete(pParse->db, $$);} sclp(A) ::= selcollist(A) COMMA. sclp(A) ::= . {A = 0;} -selcollist(A) ::= sclp(A) expr(X) as(Y). { - A = sqlite3ExprListAppend(pParse, A, X.pExpr); +selcollist(A) ::= sclp(A) scanpt(B) expr(X) scanpt(Z) as(Y). { + A = sqlite3ExprListAppend(pParse, A, X); if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1); - sqlite3ExprListSetSpan(pParse,A,&X); + sqlite3ExprListSetSpan(pParse,A,B,Z); } -selcollist(A) ::= sclp(A) STAR. { +selcollist(A) ::= sclp(A) scanpt STAR. { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); A = sqlite3ExprListAppend(pParse, A, p); } -selcollist(A) ::= sclp(A) nm(X) DOT STAR. { +selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. { Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); @@ -639,7 +671,7 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) }else{ Select *pSubquery; sqlite3SrcListShiftJoinType(F); - pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0,0); + pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0); A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,N,U); } } @@ -651,8 +683,29 @@ dbnm(A) ::= DOT nm(X). {A = X;} %type fullname {SrcList*} %destructor fullname {sqlite3SrcListDelete(pParse->db, $$);} -fullname(A) ::= nm(X) dbnm(Y). +fullname(A) ::= nm(X). { + A = sqlite3SrcListAppend(pParse->db,0,&X,0); + if( IN_RENAME_OBJECT && A ) sqlite3RenameTokenMap(pParse, A->a[0].zName, &X); +} +fullname(A) ::= nm(X) DOT nm(Y). { + A = sqlite3SrcListAppend(pParse->db,0,&X,&Y); + if( IN_RENAME_OBJECT && A ) sqlite3RenameTokenMap(pParse, A->a[0].zName, &Y); +} + +%type xfullname {SrcList*} +%destructor xfullname {sqlite3SrcListDelete(pParse->db, $$);} +xfullname(A) ::= nm(X). + {A = sqlite3SrcListAppend(pParse->db,0,&X,0); /*A-overwrites-X*/} +xfullname(A) ::= nm(X) DOT nm(Y). {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y); /*A-overwrites-X*/} +xfullname(A) ::= nm(X) DOT nm(Y) AS nm(Z). { + A = sqlite3SrcListAppend(pParse->db,0,&X,&Y); /*A-overwrites-X*/ + if( A ) A->a[0].zAlias = sqlite3NameFromToken(pParse->db, &Z); +} +xfullname(A) ::= nm(X) AS nm(Z). { + A = sqlite3SrcListAppend(pParse->db,0,&X,0); /*A-overwrites-X*/ + if( A ) A->a[0].zAlias = sqlite3NameFromToken(pParse->db, &Z); +} %type joinop {int} joinop(X) ::= COMMA|JOIN. { X = JT_INNER; } @@ -663,10 +716,27 @@ joinop(X) ::= JOIN_KW(A) nm(B) JOIN. joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN. {X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/} +// There is a parsing abiguity in an upsert statement that uses a +// SELECT on the RHS of a the INSERT: +// +// INSERT INTO tab SELECT * FROM aaa JOIN bbb ON CONFLICT ... +// here ----^^ +// +// When the ON token is encountered, the parser does not know if it is +// the beginning of an ON CONFLICT clause, or the beginning of an ON +// clause associated with the JOIN. The conflict is resolved in favor +// of the JOIN. If an ON CONFLICT clause is intended, insert a dummy +// WHERE clause in between, like this: +// +// INSERT INTO tab SELECT * FROM aaa JOIN bbb WHERE true ON CONFLICT ... +// +// The [AND] and [OR] precedence marks in the rules for on_opt cause the +// ON in this context to always be interpreted as belonging to the JOIN. +// %type on_opt {Expr*} %destructor on_opt {sqlite3ExprDelete(pParse->db, $$);} -on_opt(N) ::= ON expr(E). {N = E.pExpr;} -on_opt(N) ::= . {N = 0;} +on_opt(N) ::= ON expr(E). {N = E;} +on_opt(N) ::= . [OR] {N = 0;} // Note that this block abuses the Token type just a little. If there is // no "INDEXED BY" clause, the returned token is empty (z==0 && n==0). If @@ -702,11 +772,11 @@ using_opt(U) ::= . {U = 0;} orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). { - A = sqlite3ExprListAppend(pParse,A,Y.pExpr); + A = sqlite3ExprListAppend(pParse,A,Y); sqlite3ExprListSetSortOrder(A,Z); } sortlist(A) ::= expr(Y) sortorder(Z). { - A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/ + A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/ sqlite3ExprListSetSortOrder(A,Z); } @@ -724,9 +794,9 @@ groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;} %type having_opt {Expr*} %destructor having_opt {sqlite3ExprDelete(pParse->db, $$);} having_opt(A) ::= . {A = 0;} -having_opt(A) ::= HAVING expr(X). {A = X.pExpr;} +having_opt(A) ::= HAVING expr(X). {A = X;} -%type limit_opt {struct LimitVal} +%type limit_opt {Expr*} // The destructor for limit_opt will never fire in the current grammar. // The limit_opt non-terminal only occurs at the end of a single production @@ -735,33 +805,28 @@ having_opt(A) ::= HAVING expr(X). {A = X.pExpr;} // reduce. So there is never a limit_opt non-terminal on the stack // except as a transient. So there is never anything to destroy. // -//%destructor limit_opt { -// sqlite3ExprDelete(pParse->db, $$.pLimit); -// sqlite3ExprDelete(pParse->db, $$.pOffset); -//} -limit_opt(A) ::= . {A.pLimit = 0; A.pOffset = 0;} -limit_opt(A) ::= LIMIT expr(X). {A.pLimit = X.pExpr; A.pOffset = 0;} +//%destructor limit_opt {sqlite3ExprDelete(pParse->db, $$);} +limit_opt(A) ::= . {A = 0;} +limit_opt(A) ::= LIMIT expr(X). + {A = sqlite3PExpr(pParse,TK_LIMIT,X,0);} limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). - {A.pLimit = X.pExpr; A.pOffset = Y.pExpr;} + {A = sqlite3PExpr(pParse,TK_LIMIT,X,Y);} limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). - {A.pOffset = X.pExpr; A.pLimit = Y.pExpr;} + {A = sqlite3PExpr(pParse,TK_LIMIT,Y,X);} /////////////////////////// The DELETE statement ///////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) +cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { - sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); - W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "DELETE"); - sqlite3DeleteFrom(pParse,X,W); + sqlite3DeleteFrom(pParse,X,W,O,L); } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { - sqlite3WithPush(pParse, C, 1); +cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W). { sqlite3SrcListIndexedBy(pParse, X, &I); - sqlite3DeleteFrom(pParse,X,W); + sqlite3DeleteFrom(pParse,X,W,0,0); } %endif @@ -769,27 +834,24 @@ cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);} where_opt(A) ::= . {A = 0;} -where_opt(A) ::= WHERE expr(X). {A = X.pExpr;} +where_opt(A) ::= WHERE expr(X). {A = X;} ////////////////////////// The UPDATE command //////////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) +cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) orderby_opt(O) limit_opt(L). { - sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); - W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "UPDATE"); - sqlite3Update(pParse,X,Y,W,R); + sqlite3Update(pParse,X,Y,W,R,O,L,0); } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) +cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) where_opt(W). { - sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); - sqlite3Update(pParse,X,Y,W,R); + sqlite3Update(pParse,X,Y,W,R,0,0,0); } %endif @@ -797,32 +859,47 @@ cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) %destructor setlist {sqlite3ExprListDelete(pParse->db, $$);} setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). { - A = sqlite3ExprListAppend(pParse, A, Y.pExpr); + A = sqlite3ExprListAppend(pParse, A, Y); sqlite3ExprListSetName(pParse, A, &X, 1); } setlist(A) ::= setlist(A) COMMA LP idlist(X) RP EQ expr(Y). { - A = sqlite3ExprListAppendVector(pParse, A, X, Y.pExpr); + A = sqlite3ExprListAppendVector(pParse, A, X, Y); } setlist(A) ::= nm(X) EQ expr(Y). { - A = sqlite3ExprListAppend(pParse, 0, Y.pExpr); + A = sqlite3ExprListAppend(pParse, 0, Y); sqlite3ExprListSetName(pParse, A, &X, 1); } setlist(A) ::= LP idlist(X) RP EQ expr(Y). { - A = sqlite3ExprListAppendVector(pParse, 0, X, Y.pExpr); + A = sqlite3ExprListAppendVector(pParse, 0, X, Y); } ////////////////////////// The INSERT command ///////////////////////////////// // -cmd ::= with(W) insert_cmd(R) INTO fullname(X) idlist_opt(F) select(S). { - sqlite3WithPush(pParse, W, 1); - sqlite3Insert(pParse, X, S, F, R); +cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) select(S) + upsert(U). { + sqlite3Insert(pParse, X, S, F, R, U); } -cmd ::= with(W) insert_cmd(R) INTO fullname(X) idlist_opt(F) DEFAULT VALUES. +cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES. { - sqlite3WithPush(pParse, W, 1); - sqlite3Insert(pParse, X, 0, F, R); + sqlite3Insert(pParse, X, 0, F, R, 0); } +%type upsert {Upsert*} + +// Because upsert only occurs at the tip end of the INSERT rule for cmd, +// there is never a case where the value of the upsert pointer will not +// be destroyed by the cmd action. So comment-out the destructor to +// avoid unreachable code. +//%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} +upsert(A) ::= . { A = 0; } +upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) + DO UPDATE SET setlist(Z) where_opt(W). + { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W);} +upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING. + { A = sqlite3UpsertNew(pParse->db,T,TW,0,0); } +upsert(A) ::= ON CONFLICT DO NOTHING. + { A = sqlite3UpsertNew(pParse->db,0,0,0,0); } + %type insert_cmd {int} insert_cmd(A) ::= INSERT orconf(R). {A = R;} insert_cmd(A) ::= REPLACE. {A = OE_Replace;} @@ -835,39 +912,39 @@ insert_cmd(A) ::= REPLACE. {A = OE_Replace;} idlist_opt(A) ::= . {A = 0;} idlist_opt(A) ::= LP idlist(X) RP. {A = X;} idlist(A) ::= idlist(A) COMMA nm(Y). - {A = sqlite3IdListAppend(pParse->db,A,&Y);} + {A = sqlite3IdListAppend(pParse,A,&Y);} idlist(A) ::= nm(Y). - {A = sqlite3IdListAppend(pParse->db,0,&Y); /*A-overwrites-Y*/} + {A = sqlite3IdListAppend(pParse,0,&Y); /*A-overwrites-Y*/} /////////////////////////// Expression Processing ///////////////////////////// // -%type expr {ExprSpan} -%destructor expr {sqlite3ExprDelete(pParse->db, $$.pExpr);} -%type term {ExprSpan} -%destructor term {sqlite3ExprDelete(pParse->db, $$.pExpr);} +%type expr {Expr*} +%destructor expr {sqlite3ExprDelete(pParse->db, $$);} +%type term {Expr*} +%destructor term {sqlite3ExprDelete(pParse->db, $$);} %include { - /* This is a utility routine used to set the ExprSpan.zStart and - ** ExprSpan.zEnd values of pOut so that the span covers the complete - ** range of text beginning with pStart and going to the end of pEnd. - */ - static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){ - pOut->zStart = pStart->z; - pOut->zEnd = &pEnd->z[pEnd->n]; - } /* Construct a new Expr object from a single identifier. Use the ** new Expr to populate pOut. Set the span of pOut to be the identifier ** that created the expression. */ - static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){ + static Expr *tokenExpr(Parse *pParse, int op, Token t){ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); if( p ){ - memset(p, 0, sizeof(Expr)); + /* memset(p, 0, sizeof(Expr)); */ p->op = (u8)op; + p->affinity = 0; p->flags = EP_Leaf; p->iAgg = -1; + p->pLeft = p->pRight = 0; + p->x.pList = 0; + p->pAggInfo = 0; + p->y.pTab = 0; + p->op2 = 0; + p->iTable = 0; + p->iColumn = 0; p->u.zToken = (char*)&p[1]; memcpy(p->u.zToken, t.z, t.n); p->u.zToken[t.n] = 0; @@ -878,137 +955,119 @@ idlist(A) ::= nm(Y). #if SQLITE_MAX_EXPR_DEPTH>0 p->nHeight = 1; #endif + if( IN_RENAME_OBJECT ){ + return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t); + } } - pOut->pExpr = p; - pOut->zStart = t.z; - pOut->zEnd = &t.z[t.n]; + return p; } + } expr(A) ::= term(A). -expr(A) ::= LP(B) expr(X) RP(E). - {spanSet(&A,&B,&E); /*A-overwrites-B*/ A.pExpr = X.pExpr;} -expr(A) ::= id(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/} -expr(A) ::= JOIN_KW(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/} +expr(A) ::= LP expr(X) RP. {A = X;} +expr(A) ::= id(X). {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/} +expr(A) ::= JOIN_KW(X). {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/} expr(A) ::= nm(X) DOT nm(Y). { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1); - spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)temp2, &Y); + sqlite3RenameTokenMap(pParse, (void*)temp1, &X); + } + A = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1); Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &Z, 1); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); - spanSet(&A,&X,&Z); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)temp3, &Z); + sqlite3RenameTokenMap(pParse, (void*)temp2, &Y); + } + A = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } -term(A) ::= NULL|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/} -term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/} +term(A) ::= NULL|FLOAT|BLOB(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/} +term(A) ::= STRING(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/} term(A) ::= INTEGER(X). { - A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1); - A.zStart = X.z; - A.zEnd = X.z + X.n; + A = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1); } expr(A) ::= VARIABLE(X). { if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){ u32 n = X.n; - spanExpr(&A, pParse, TK_VARIABLE, X); - sqlite3ExprAssignVarNumber(pParse, A.pExpr, n); + A = tokenExpr(pParse, TK_VARIABLE, X); + sqlite3ExprAssignVarNumber(pParse, A, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers ** in the virtual machine. #N is the N-th register. */ Token t = X; /*A-overwrites-X*/ assert( t.n>=2 ); - spanSet(&A, &t, &t); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - A.pExpr = 0; + A = 0; }else{ - A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable); + A = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( A ) sqlite3GetInt32(&t.z[1], &A->iTable); } } } expr(A) ::= expr(A) COLLATE ids(C). { - A.pExpr = sqlite3ExprAddCollateToken(pParse, A.pExpr, &C, 1); - A.zEnd = &C.z[C.n]; + A = sqlite3ExprAddCollateToken(pParse, A, &C, 1); } %ifndef SQLITE_OMIT_CAST -expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { - spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1); - sqlite3ExprAttachSubtrees(pParse->db, A.pExpr, E.pExpr, 0); +expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. { + A = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1); + sqlite3ExprAttachSubtrees(pParse->db, A, E, 0); } %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 distinct(D) exprlist(Y) RP. { + A = sqlite3ExprFunction(pParse, Y, &X, D); } -expr(A) ::= id(X) LP STAR RP(E). { - A.pExpr = sqlite3ExprFunction(pParse, 0, &X); - spanSet(&A,&X,&E); +expr(A) ::= id(X) LP STAR RP. { + A = sqlite3ExprFunction(pParse, 0, &X, 0); } + +%ifndef SQLITE_OMIT_WINDOWFUNC +expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP over_clause(Z). { + A = sqlite3ExprFunction(pParse, Y, &X, D); + sqlite3WindowAttach(pParse, A, Z); +} +expr(A) ::= id(X) LP STAR RP over_clause(Z). { + A = sqlite3ExprFunction(pParse, 0, &X, 0); + sqlite3WindowAttach(pParse, A, Z); +} +%endif + term(A) ::= CTIME_KW(OP). { - A.pExpr = sqlite3ExprFunction(pParse, 0, &OP); - spanSet(&A, &OP, &OP); + A = sqlite3ExprFunction(pParse, 0, &OP, 0); } -%include { - /* This routine constructs a binary expression node out of two ExprSpan - ** objects and uses the result to populate a new ExprSpan object. - */ - static void spanBinaryExpr( - Parse *pParse, /* The parsing context. Errors accumulate here */ - int op, /* The binary operation */ - ExprSpan *pLeft, /* The left operand, and output */ - ExprSpan *pRight /* The right operand */ - ){ - pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr); - pLeft->zEnd = pRight->zEnd; - } - - /* If doNot is true, then add a TK_NOT Expr-node wrapper around the - ** outside of *ppExpr. - */ - static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){ - if( doNot ){ - pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0); - } - } -} - -expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). { - ExprList *pList = sqlite3ExprListAppend(pParse, X, Y.pExpr); - A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( A.pExpr ){ - A.pExpr->x.pList = pList; - spanSet(&A, &L, &R); +expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. { + ExprList *pList = sqlite3ExprListAppend(pParse, X, Y); + A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( A ){ + A->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } } -expr(A) ::= expr(A) AND(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} -expr(A) ::= expr(A) OR(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} +expr(A) ::= expr(A) AND(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);} +expr(A) ::= expr(A) OR(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);} expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y). - {spanBinaryExpr(pParse,@OP,&A,&Y);} -expr(A) ::= expr(A) EQ|NE(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} + {A=sqlite3PExpr(pParse,@OP,A,Y);} +expr(A) ::= expr(A) EQ|NE(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);} expr(A) ::= expr(A) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y). - {spanBinaryExpr(pParse,@OP,&A,&Y);} + {A=sqlite3PExpr(pParse,@OP,A,Y);} expr(A) ::= expr(A) PLUS|MINUS(OP) expr(Y). - {spanBinaryExpr(pParse,@OP,&A,&Y);} + {A=sqlite3PExpr(pParse,@OP,A,Y);} expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y). - {spanBinaryExpr(pParse,@OP,&A,&Y);} -expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} + {A=sqlite3PExpr(pParse,@OP,A,Y);} +expr(A) ::= expr(A) CONCAT(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);} %type likeop {Token} likeop(A) ::= LIKE_KW|MATCH(A). likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/} @@ -1016,49 +1075,33 @@ expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] { ExprList *pList; int bNot = OP.n & 0x80000000; OP.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, A.pExpr); - A.pExpr = sqlite3ExprFunction(pParse, pList, &OP); - exprNot(pParse, bNot, &A); - A.zEnd = Y.zEnd; - if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, Y); + pList = sqlite3ExprListAppend(pParse,pList, A); + A = sqlite3ExprFunction(pParse, pList, &OP, 0); + if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); + if( A ) A->flags |= EP_InfixFunc; } expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] { ExprList *pList; int bNot = OP.n & 0x80000000; OP.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, A.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, E.pExpr); - A.pExpr = sqlite3ExprFunction(pParse, pList, &OP); - exprNot(pParse, bNot, &A); - A.zEnd = E.zEnd; - if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, Y); + pList = sqlite3ExprListAppend(pParse,pList, A); + pList = sqlite3ExprListAppend(pParse,pList, E); + A = sqlite3ExprFunction(pParse, pList, &OP, 0); + if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); + if( A ) A->flags |= EP_InfixFunc; } -%include { - /* Construct an expression node for a unary postfix operator - */ - static void spanUnaryPostfix( - Parse *pParse, /* Parsing context to record errors */ - int op, /* The operator */ - ExprSpan *pOperand, /* The operand, and output */ - Token *pPostOp /* The operand token for setting the span */ - ){ - pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); - pOperand->zEnd = &pPostOp->z[pPostOp->n]; - } -} - -expr(A) ::= expr(A) ISNULL|NOTNULL(E). {spanUnaryPostfix(pParse,@E,&A,&E);} -expr(A) ::= expr(A) NOT NULL(E). {spanUnaryPostfix(pParse,TK_NOTNULL,&A,&E);} +expr(A) ::= expr(A) ISNULL|NOTNULL(E). {A = sqlite3PExpr(pParse,@E,A,0);} +expr(A) ::= expr(A) NOT NULL. {A = sqlite3PExpr(pParse,TK_NOTNULL,A,0);} %include { /* A routine to convert a binary TK_IS or TK_ISNOT expression into a ** unary TK_ISNULL or TK_NOTNULL expression. */ static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ sqlite3 *db = pParse->db; - if( pA && pY && pY->op==TK_NULL ){ + if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){ pA->op = (u8)op; sqlite3ExprDelete(db, pA->pRight); pA->pRight = 0; @@ -1073,61 +1116,42 @@ expr(A) ::= expr(A) NOT NULL(E). {spanUnaryPostfix(pParse,TK_NOTNULL,&A,&E);} // is any other expression, code as TK_IS or TK_ISNOT. // expr(A) ::= expr(A) IS expr(Y). { - spanBinaryExpr(pParse,TK_IS,&A,&Y); - binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_ISNULL); + A = sqlite3PExpr(pParse,TK_IS,A,Y); + binaryToUnaryIfNull(pParse, Y, A, TK_ISNULL); } expr(A) ::= expr(A) IS NOT expr(Y). { - spanBinaryExpr(pParse,TK_ISNOT,&A,&Y); - binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_NOTNULL); + A = sqlite3PExpr(pParse,TK_ISNOT,A,Y); + binaryToUnaryIfNull(pParse, Y, A, TK_NOTNULL); } -%include { - /* Construct an expression node for a unary prefix operator - */ - static void spanUnaryPrefix( - ExprSpan *pOut, /* Write the new expression node here */ - Parse *pParse, /* Parsing context to record errors */ - int op, /* The operator */ - ExprSpan *pOperand, /* The operand */ - Token *pPreOp /* The operand token for setting the span */ - ){ - pOut->zStart = pPreOp->z; - pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); - pOut->zEnd = pOperand->zEnd; - } -} - - - expr(A) ::= NOT(B) expr(X). - {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/} + {A = sqlite3PExpr(pParse, @B, X, 0);/*A-overwrites-B*/} expr(A) ::= BITNOT(B) expr(X). - {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/} -expr(A) ::= MINUS(B) expr(X). [BITNOT] - {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);/*A-overwrites-B*/} -expr(A) ::= PLUS(B) expr(X). [BITNOT] - {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);/*A-overwrites-B*/} + {A = sqlite3PExpr(pParse, @B, X, 0);/*A-overwrites-B*/} +expr(A) ::= PLUS|MINUS(B) expr(X). [BITNOT] { + A = sqlite3PExpr(pParse, @B==TK_PLUS ? TK_UPLUS : TK_UMINUS, X, 0); + /*A-overwrites-B*/ +} %type between_op {int} between_op(A) ::= BETWEEN. {A = 0;} between_op(A) ::= NOT BETWEEN. {A = 1;} expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { - ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, Y.pExpr); - A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, A.pExpr, 0); - if( A.pExpr ){ - A.pExpr->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, X); + pList = sqlite3ExprListAppend(pParse,pList, Y); + A = sqlite3PExpr(pParse, TK_BETWEEN, A, 0); + if( A ){ + A->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - exprNot(pParse, N, &A); - A.zEnd = Y.zEnd; + if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); } %ifndef SQLITE_OMIT_SUBQUERY %type in_op {int} in_op(A) ::= IN. {A = 0;} in_op(A) ::= NOT IN. {A = 1;} - expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP(E). [IN] { + expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP. [IN] { if( Y==0 ){ /* Expressions of the form ** @@ -1137,8 +1161,8 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprDelete(pParse->db, A.pExpr); - A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1); + sqlite3ExprDelete(pParse->db, A); + A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1); }else if( Y->nExpr==1 ){ /* Expressions of the form: ** @@ -1165,54 +1189,48 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { pRHS->flags &= ~EP_Collate; pRHS->flags |= EP_Generic; } - A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A.pExpr, pRHS); + A = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A, pRHS); }else{ - A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0); - if( A.pExpr ){ - A.pExpr->x.pList = Y; - sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); + A = sqlite3PExpr(pParse, TK_IN, A, 0); + if( A ){ + A->x.pList = Y; + sqlite3ExprSetHeightAndFlags(pParse, A); }else{ sqlite3ExprListDelete(pParse->db, Y); } - exprNot(pParse, N, &A); + if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); } - A.zEnd = &E.z[E.n]; } - expr(A) ::= LP(B) select(X) RP(E). { - spanSet(&A,&B,&E); /*A-overwrites-B*/ - A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, A.pExpr, X); + expr(A) ::= LP select(X) RP. { + A = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, A, X); } - expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] { - A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0); - sqlite3PExprAddSelect(pParse, A.pExpr, Y); - exprNot(pParse, N, &A); - A.zEnd = &E.z[E.n]; + expr(A) ::= expr(A) in_op(N) LP select(Y) RP. [IN] { + A = sqlite3PExpr(pParse, TK_IN, A, 0); + sqlite3PExprAddSelect(pParse, A, Y); + if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); } expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); - Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); if( E ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E); - A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0); - sqlite3PExprAddSelect(pParse, A.pExpr, pSelect); - exprNot(pParse, N, &A); - A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n]; + A = sqlite3PExpr(pParse, TK_IN, A, 0); + sqlite3PExprAddSelect(pParse, A, pSelect); + if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); } - expr(A) ::= EXISTS(B) LP select(Y) RP(E). { + expr(A) ::= EXISTS LP select(Y) RP. { Expr *p; - spanSet(&A,&B,&E); /*A-overwrites-B*/ - p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + p = A = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); sqlite3PExprAddSelect(pParse, p, Y); } %endif SQLITE_OMIT_SUBQUERY /* CASE expressions */ -expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { - spanSet(&A,&C,&E); /*A-overwrites-C*/ - A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0); - if( A.pExpr ){ - A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y; - sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); +expr(A) ::= CASE case_operand(X) case_exprlist(Y) case_else(Z) END. { + A = sqlite3PExpr(pParse, TK_CASE, X, 0); + if( A ){ + A->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y; + sqlite3ExprSetHeightAndFlags(pParse, A); }else{ sqlite3ExprListDelete(pParse->db, Y); sqlite3ExprDelete(pParse->db, Z); @@ -1221,20 +1239,20 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { %type case_exprlist {ExprList*} %destructor case_exprlist {sqlite3ExprListDelete(pParse->db, $$);} case_exprlist(A) ::= case_exprlist(A) WHEN expr(Y) THEN expr(Z). { - A = sqlite3ExprListAppend(pParse,A, Y.pExpr); - A = sqlite3ExprListAppend(pParse,A, Z.pExpr); + A = sqlite3ExprListAppend(pParse,A, Y); + A = sqlite3ExprListAppend(pParse,A, Z); } case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). { - A = sqlite3ExprListAppend(pParse,0, Y.pExpr); - A = sqlite3ExprListAppend(pParse,A, Z.pExpr); + A = sqlite3ExprListAppend(pParse,0, Y); + A = sqlite3ExprListAppend(pParse,A, Z); } %type case_else {Expr*} %destructor case_else {sqlite3ExprDelete(pParse->db, $$);} -case_else(A) ::= ELSE expr(X). {A = X.pExpr;} +case_else(A) ::= ELSE expr(X). {A = X;} case_else(A) ::= . {A = 0;} %type case_operand {Expr*} %destructor case_operand {sqlite3ExprDelete(pParse->db, $$);} -case_operand(A) ::= expr(X). {A = X.pExpr; /*A-overwrites-X*/} +case_operand(A) ::= expr(X). {A = X; /*A-overwrites-X*/} case_operand(A) ::= . {A = 0;} %type exprlist {ExprList*} @@ -1245,9 +1263,9 @@ case_operand(A) ::= . {A = 0;} exprlist(A) ::= nexprlist(A). exprlist(A) ::= . {A = 0;} nexprlist(A) ::= nexprlist(A) COMMA expr(Y). - {A = sqlite3ExprListAppend(pParse,A,Y.pExpr);} + {A = sqlite3ExprListAppend(pParse,A,Y);} nexprlist(A) ::= expr(Y). - {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/} + {A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/} %ifndef SQLITE_OMIT_SUBQUERY /* A paren_exprlist is an optional expression list contained inside @@ -1266,6 +1284,9 @@ cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U, &S, W, SQLITE_SO_ASC, NE, SQLITE_IDXTYPE_APPDEF); + if( IN_RENAME_OBJECT && pParse->pNewIndex ){ + sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &Y); + } } %type uniqueflag {int} @@ -1401,7 +1422,7 @@ foreach_clause ::= FOR EACH ROW. %type when_clause {Expr*} %destructor when_clause {sqlite3ExprDelete(pParse->db, $$);} when_clause(A) ::= . { A = 0; } -when_clause(A) ::= WHEN expr(X). { A = X.pExpr; } +when_clause(A) ::= WHEN expr(X). { A = X; } %type trigger_cmd_list {TriggerStep*} %destructor trigger_cmd_list {sqlite3DeleteTriggerStep(pParse->db, $$);} @@ -1450,34 +1471,33 @@ tridxby ::= NOT INDEXED. { %destructor trigger_cmd {sqlite3DeleteTriggerStep(pParse->db, $$);} // UPDATE trigger_cmd(A) ::= - UPDATE orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z). - {A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R);} + UPDATE(B) orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z) scanpt(E). + {A = sqlite3TriggerUpdateStep(pParse, &X, Y, Z, R, B.z, E);} // INSERT -trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) idlist_opt(F) select(S). - {A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);/*A-overwrites-R*/} - +trigger_cmd(A) ::= scanpt(B) insert_cmd(R) INTO + trnm(X) idlist_opt(F) select(S) upsert(U) scanpt(Z). { + A = sqlite3TriggerInsertStep(pParse,&X,F,S,R,U,B,Z);/*A-overwrites-R*/ +} // DELETE -trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y). - {A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);} +trigger_cmd(A) ::= DELETE(B) FROM trnm(X) tridxby where_opt(Y) scanpt(E). + {A = sqlite3TriggerDeleteStep(pParse, &X, Y, B.z, E);} // SELECT -trigger_cmd(A) ::= select(X). - {A = sqlite3TriggerSelectStep(pParse->db, X); /*A-overwrites-X*/} +trigger_cmd(A) ::= scanpt(B) select(X) scanpt(E). + {A = sqlite3TriggerSelectStep(pParse->db, X, B, E); /*A-overwrites-X*/} // The special RAISE expression that may occur in trigger programs -expr(A) ::= RAISE(X) LP IGNORE RP(Y). { - spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( A.pExpr ){ - A.pExpr->affinity = OE_Ignore; +expr(A) ::= RAISE LP IGNORE RP. { + A = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( A ){ + A->affinity = OE_Ignore; } } -expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). { - spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1); - if( A.pExpr ) { - A.pExpr->affinity = (char)T; +expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. { + A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1); + if( A ) { + A->affinity = (char)T; } } %endif !SQLITE_OMIT_TRIGGER @@ -1498,16 +1518,16 @@ cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). { //////////////////////// ATTACH DATABASE file AS name ///////////////////////// %ifndef SQLITE_OMIT_ATTACH cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). { - sqlite3Attach(pParse, F.pExpr, D.pExpr, K); + sqlite3Attach(pParse, F, D, K); } cmd ::= DETACH database_kw_opt expr(D). { - sqlite3Detach(pParse, D.pExpr); + sqlite3Detach(pParse, D); } %type key_opt {Expr*} %destructor key_opt {sqlite3ExprDelete(pParse->db, $$);} key_opt(A) ::= . { A = 0; } -key_opt(A) ::= KEY expr(X). { A = X.pExpr; } +key_opt(A) ::= KEY expr(X). { A = X; } database_kw_opt ::= DATABASE. database_kw_opt ::= . @@ -1539,8 +1559,13 @@ add_column_fullname ::= fullname(X). { disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, X); } +cmd ::= ALTER TABLE fullname(X) RENAME kwcolumn_opt nm(Y) TO nm(Z). { + sqlite3AlterRenameColumn(pParse, X, &Y, &Z); +} + kwcolumn_opt ::= . kwcolumn_opt ::= COLUMNKW. + %endif SQLITE_OMIT_ALTERTABLE //////////////////////// CREATE VIRTUAL TABLE ... ///////////////////////////// @@ -1565,15 +1590,13 @@ anylist ::= anylist ANY. //////////////////////// COMMON TABLE EXPRESSIONS //////////////////////////// -%type with {With*} %type wqlist {With*} -%destructor with {sqlite3WithDelete(pParse->db, $$);} %destructor wqlist {sqlite3WithDelete(pParse->db, $$);} -with(A) ::= . {A = 0;} +with ::= . %ifndef SQLITE_OMIT_CTE -with(A) ::= WITH wqlist(W). { A = W; } -with(A) ::= WITH RECURSIVE wqlist(W). { A = W; } +with ::= WITH wqlist(W). { sqlite3WithPush(pParse, W, 1); } +with ::= WITH RECURSIVE wqlist(W). { sqlite3WithPush(pParse, W, 1); } wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. { A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/ @@ -1582,3 +1605,108 @@ wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. { A = sqlite3WithAdd(pParse, A, &X, Y, Z); } %endif SQLITE_OMIT_CTE + +//////////////////////// WINDOW FUNCTION EXPRESSIONS ///////////////////////// +// These must be at the end of this file. Specifically, the rules that +// introduce tokens WINDOW, OVER and FILTER must appear last. This causes +// the integer values assigned to these tokens to be larger than all other +// tokens that may be output by the tokenizer except TK_SPACE and TK_ILLEGAL. +// +%ifndef SQLITE_OMIT_WINDOWFUNC +%type windowdefn_list {Window*} +%destructor windowdefn_list {sqlite3WindowListDelete(pParse->db, $$);} +windowdefn_list(A) ::= windowdefn(Z). { A = Z; } +windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). { + assert( Z!=0 ); + Z->pNextWin = Y; + A = Z; +} + +%type windowdefn {Window*} +%destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);} +windowdefn(A) ::= nm(X) AS window(Y). { + if( ALWAYS(Y) ){ + Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n); + } + A = Y; +} + +%type window {Window*} +%destructor window {sqlite3WindowDelete(pParse->db, $$);} + +%type frame_opt {Window*} +%destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);} + +%type part_opt {ExprList*} +%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);} + +%type filter_opt {Expr*} +%destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);} + +%type range_or_rows {int} + +%type frame_bound {struct FrameBound} +%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);} +%type frame_bound_s {struct FrameBound} +%destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);} +%type frame_bound_e {struct FrameBound} +%destructor frame_bound_e {sqlite3ExprDelete(pParse->db, $$.pExpr);} + +window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. { + A = Z; + if( ALWAYS(A) ){ + A->pPartition = X; + A->pOrderBy = Y; + } +} + +part_opt(A) ::= PARTITION BY nexprlist(X). { A = X; } +part_opt(A) ::= . { A = 0; } + +frame_opt(A) ::= . { + A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0); +} +frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y). { + A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0); +} +frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND frame_bound_e(Z). { + A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr); +} + +range_or_rows(A) ::= RANGE. { A = TK_RANGE; } +range_or_rows(A) ::= ROWS. { A = TK_ROWS; } + + +frame_bound_s(A) ::= frame_bound(X). { A = X; } +frame_bound_s(A) ::= UNBOUNDED PRECEDING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;} +frame_bound_e(A) ::= frame_bound(X). { A = X; } +frame_bound_e(A) ::= UNBOUNDED FOLLOWING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;} + +frame_bound(A) ::= expr(X) PRECEDING. { A.eType = TK_PRECEDING; A.pExpr = X; } +frame_bound(A) ::= CURRENT ROW. { A.eType = TK_CURRENT ; A.pExpr = 0; } +frame_bound(A) ::= expr(X) FOLLOWING. { A.eType = TK_FOLLOWING; A.pExpr = X; } + +%type window_clause {Window*} +%destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);} +window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; } + +%type over_clause {Window*} +%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);} +over_clause(A) ::= filter_opt(W) OVER window(Z). { + A = Z; + assert( A!=0 ); + A->pFilter = W; +} +over_clause(A) ::= filter_opt(W) OVER nm(Z). { + A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( A ){ + A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n); + A->pFilter = W; + }else{ + sqlite3ExprDelete(pParse->db, W); + } +} + +filter_opt(A) ::= . { A = 0; } +filter_opt(A) ::= FILTER LP WHERE expr(X) RP. { A = X; } +%endif /* SQLITE_OMIT_WINDOWFUNC */ diff --git a/src/pcache.c b/src/pcache.c index dc7d00f306..7415378b4f 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -32,7 +32,7 @@ ** The PCache.pSynced variable is used to optimize searching for a dirty ** page to eject from the cache mid-transaction. It is better to eject ** a page that does not require a journal sync than one that does. -** Therefore, pSynced is maintained to that it *almost* always points +** Therefore, pSynced is maintained so that it *almost* always points ** to either the oldest page in the pDirty/pDirtyTail list that has a ** clear PGHDR_NEED_SYNC flag or to a page that is older than this one ** (so that the right page to eject can be found by following pDirtyPrev @@ -191,12 +191,9 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ p->eCreate = 2; } } - pPage->pDirtyNext = 0; - pPage->pDirtyPrev = 0; } if( addRemove & PCACHE_DIRTYLIST_ADD ){ - assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); - + pPage->pDirtyPrev = 0; pPage->pDirtyNext = p->pDirty; if( pPage->pDirtyNext ){ assert( pPage->pDirtyNext->pDirtyPrev==0 ); @@ -434,7 +431,7 @@ int sqlite3PcacheFetchStress( sqlite3_log(SQLITE_FULL, "spill page %d making room for %d - cache used: %d/%d", pPg->pgno, pgno, - sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), + sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache), numberOfCachePages(pCache)); #endif pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); @@ -513,11 +510,7 @@ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ if( (--p->nRef)==0 ){ if( p->flags&PGHDR_CLEAN ){ pcacheUnpin(p); - }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/ - /* Move the page to the head of the dirty list. If p->pDirtyPrev==0, - ** then page p is already at the head of the dirty list and the - ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE - ** tag above. */ + }else{ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); } } @@ -573,16 +566,15 @@ void sqlite3PcacheMakeDirty(PgHdr *p){ */ void sqlite3PcacheMakeClean(PgHdr *p){ assert( sqlite3PcachePageSanity(p) ); - if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){ - assert( (p->flags & PGHDR_CLEAN)==0 ); - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); - p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); - p->flags |= PGHDR_CLEAN; - pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); - assert( sqlite3PcachePageSanity(p) ); - if( p->nRef==0 ){ - pcacheUnpin(p); - } + assert( (p->flags & PGHDR_DIRTY)!=0 ); + assert( (p->flags & PGHDR_CLEAN)==0 ); + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); + p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); + p->flags |= PGHDR_CLEAN; + pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); + assert( sqlite3PcachePageSanity(p) ); + if( p->nRef==0 ){ + pcacheUnpin(p); } } diff --git a/src/pcache.h b/src/pcache.h index 864ce5bb4a..bbc2cb4539 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -43,6 +43,8 @@ struct PgHdr { i16 nRef; /* Number of users of this page */ PgHdr *pDirtyNext; /* Next element in list of dirty pages */ PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ + /* NB: pDirtyNext and pDirtyPrev are undefined if the + ** PgHdr object is not dirty */ }; /* Bit values for PgHdr.flags */ diff --git a/src/pcache1.c b/src/pcache1.c index 9c59574ace..fc3cbc5abe 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -137,7 +137,7 @@ struct PGroup { unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ unsigned int nMinPage; /* Sum of nMin for purgeable caches */ unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ - unsigned int nCurrentPage; /* Number of purgeable pages allocated */ + unsigned int nPurgeable; /* Number of purgeable pages allocated */ PgHdr1 lru; /* The beginning and end of the LRU list */ }; @@ -151,11 +151,13 @@ struct PGroup { */ struct PCache1 { /* Cache configuration parameters. Page size (szPage) and the purgeable - ** flag (bPurgeable) are set when the cache is created. nMax may be + ** flag (bPurgeable) and the pnPurgeable pointer are all set when the + ** cache is created and are never changed thereafter. nMax may be ** modified at any time by a call to the pcache1Cachesize() method. ** The PGroup mutex must be held when accessing nMax. */ PGroup *pGroup; /* PGroup this cache belongs to */ + unsigned int *pnPurgeable; /* Pointer to pGroup->nPurgeable */ int szPage; /* Size of database content section */ int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */ int szAlloc; /* Total size of one pcache line */ @@ -250,6 +252,7 @@ void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ if( pcache1.isInit ){ PgFreeslot *p; if( pBuf==0 ) sz = n = 0; + if( n==0 ) sz = 0; sz = ROUNDDOWN8(sz); pcache1.szSlot = sz; pcache1.nSlot = pcache1.nFreeSlot = n; @@ -442,9 +445,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ p->isBulkLocal = 0; p->isAnchor = 0; } - if( pCache->bPurgeable ){ - pCache->pGroup->nCurrentPage++; - } + (*pCache->pnPurgeable)++; return p; } @@ -465,9 +466,7 @@ static void pcache1FreePage(PgHdr1 *p){ sqlite3_free(p); #endif } - if( pCache->bPurgeable ){ - pCache->pGroup->nCurrentPage--; - } + (*pCache->pnPurgeable)--; } /* @@ -607,7 +606,7 @@ static void pcache1EnforceMaxPage(PCache1 *pCache){ PGroup *pGroup = pCache->pGroup; PgHdr1 *p; assert( sqlite3_mutex_held(pGroup->mutex) ); - while( pGroup->nCurrentPage>pGroup->nMaxPage + while( pGroup->nPurgeable>pGroup->nMaxPage && (p=pGroup->lru.pLruPrev)->isAnchor==0 ){ assert( p->pCache->pGroup==pGroup ); @@ -778,6 +777,10 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ pCache->nMin = 10; pGroup->nMinPage += pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pCache->pnPurgeable = &pGroup->nPurgeable; + }else{ + static unsigned int dummyCurrentPage; + pCache->pnPurgeable = &dummyCurrentPage; } pcache1LeaveMutex(pGroup); if( pCache->nHash==0 ){ @@ -887,7 +890,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( pcache1FreePage(pPage); pPage = 0; }else{ - pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); + pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable); } } @@ -1068,7 +1071,7 @@ static void pcache1Unpin( assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); assert( PAGE_IS_PINNED(pPage) ); - if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ + if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){ pcache1RemoveFromHash(pPage, 1); }else{ /* Add the page to the PGroup LRU list. */ @@ -1247,7 +1250,7 @@ void sqlite3PcacheStats( assert( PAGE_IS_UNPINNED(p) ); nRecyclable++; } - *pnCurrent = pcache1.grp.nCurrentPage; + *pnCurrent = pcache1.grp.nPurgeable; *pnMax = (int)pcache1.grp.nMaxPage; *pnMin = (int)pcache1.grp.nMinPage; *pnRecyclable = nRecyclable; diff --git a/src/pragma.c b/src/pragma.c index e640c7ebe5..fd08cc202c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -298,16 +298,16 @@ static const PragmaName *pragmaLocate(const char *zName){ /* ** Helper subroutine for PRAGMA integrity_check: ** -** Generate code to output a single-column result row with the result -** held in register regResult. Decrement the result count and halt if -** the maximum number of result rows have been issued. +** Generate code to output a single-column result row with a value of the +** string held in register 3. Decrement the result count in register 1 +** and halt if the maximum number of result rows have been issued. */ -static int integrityCheckResultRow(Vdbe *v, int regResult){ +static int integrityCheckResultRow(Vdbe *v){ int addr; - sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeAddOp0(v, OP_Halt); return addr; } @@ -1080,6 +1080,7 @@ void sqlite3Pragma( ** type: Column declaration type. ** notnull: True if 'NOT NULL' is part of column declaration ** dflt_value: The default value for the column, if any. + ** pk: Non-zero for PK fields. */ case PragTyp_TABLE_INFO: if( zRight ){ Table *pTab; @@ -1089,11 +1090,12 @@ void sqlite3Pragma( int nHidden = 0; Column *pCol; Index *pPk = sqlite3PrimaryKeyIndex(pTab); - pParse->nMem = 6; + pParse->nMem = 7; sqlite3CodeVerifySchema(pParse, iDb); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ - if( IsHiddenColumn(pCol) ){ + int isHidden = IsHiddenColumn(pCol); + if( isHidden && pPragma->iArg==0 ){ nHidden++; continue; } @@ -1105,13 +1107,14 @@ void sqlite3Pragma( for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN ); - sqlite3VdbeMultiLoad(v, 1, "issisi", + sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", i-nHidden, pCol->zName, sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, pCol->pDflt ? pCol->pDflt->u.zToken : 0, - k); + k, + isHidden); } } } @@ -1234,13 +1237,11 @@ void sqlite3Pragma( for(i=0; iu.pHash ){ sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } } for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ p = (FuncDef*)sqliteHashData(j); sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } } break; @@ -1252,7 +1253,6 @@ void sqlite3Pragma( for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){ Module *pMod = (Module*)sqliteHashData(j); sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } } break; @@ -1262,7 +1262,6 @@ void sqlite3Pragma( int i; for(i=0; inDb; i++){ - HashElem *x; - Hash *pTbls; - int *aRoot; - int cnt = 0; - int mxIdx = 0; - int nIdx; + HashElem *x; /* For looping over tables in the schema */ + Hash *pTbls; /* Set of all tables in the schema */ + int *aRoot; /* Array of root page numbers of all btrees */ + int cnt = 0; /* Number of entries in aRoot[] */ + int mxIdx = 0; /* Maximum number of indexes for any table */ if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; @@ -1508,8 +1506,9 @@ void sqlite3Pragma( assert( sqlite3SchemaMutexHeld(db, i, 0) ); pTbls = &db->aDb[i].pSchema->tblHash; for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ - Table *pTab = sqliteHashData(x); - Index *pIdx; + Table *pTab = sqliteHashData(x); /* Current table */ + Index *pIdx; /* An index on pTab */ + int nIdx; /* Number of indexes on pTab */ if( HasRowid(pTab) ) cnt++; for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } if( nIdx>mxIdx ) mxIdx = nIdx; @@ -1519,12 +1518,12 @@ void sqlite3Pragma( for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; - if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum; + if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - aRoot[cnt++] = pIdx->tnum; + aRoot[++cnt] = pIdx->tnum; } } - aRoot[cnt] = 0; + aRoot[0] = cnt; /* Make sure sufficient number of registers have been allocated */ pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); @@ -1537,9 +1536,8 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), P4_DYNAMIC); - sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); - integrityCheckResultRow(v, 2); + sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3); + integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. @@ -1553,16 +1551,12 @@ void sqlite3Pragma( int r1 = -1; if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */ - if( pTab->pCheck==0 - && (pTab->tabFlags & TF_HasNotNull)==0 - && (pTab->pIndex==0 || isQuick) - ){ - continue; /* No additional checks needed for this table */ - } pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); - sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); + /* reg[7] counts the number of entries in the table. + ** reg[8+i] counts the number of entries in the i-th index + */ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ @@ -1571,6 +1565,11 @@ void sqlite3Pragma( assert( sqlite3NoTempsInRange(pParse,1,7+j) ); sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); + if( !isQuick ){ + /* Sanity check on record header decoding */ + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + } /* Verify that all NOT NULL columns really are NOT NULL */ for(j=0; jnCol; j++){ char *zErr; @@ -1583,7 +1582,7 @@ void sqlite3Pragma( zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pTab->aCol[j].zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - integrityCheckResultRow(v, 3); + integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, jmp2); } /* Verify CHECK constraints */ @@ -1595,7 +1594,6 @@ void sqlite3Pragma( char *zErr; int k; pParse->iSelfTab = iDataCur + 1; - sqlite3ExprCachePush(pParse); for(k=pCheck->nExpr-1; k>0; k--){ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); } @@ -1606,57 +1604,58 @@ void sqlite3Pragma( zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", pTab->zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - integrityCheckResultRow(v, 3); + integrityCheckResultRow(v); sqlite3VdbeResolveLabel(v, addrCkOk); - sqlite3ExprCachePop(pParse); } sqlite3ExprListDelete(db, pCheck); } - /* Validate index entries for the current row */ - for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){ - int jmp2, jmp3, jmp4, jmp5; - int ckUniq = sqlite3VdbeMakeLabel(v); - if( pPk==pIdx ) continue; - r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, - pPrior, r1); - pPrior = pIdx; - sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ - /* Verify that an index entry exists for the current table row */ - jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, - pIdx->nColumn); VdbeCoverage(v); - sqlite3VdbeLoadString(v, 3, "row "); - sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); - sqlite3VdbeLoadString(v, 4, " missing from index "); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); - jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); - jmp4 = integrityCheckResultRow(v, 3); - sqlite3VdbeJumpHere(v, jmp2); - /* For UNIQUE indexes, verify that only one entry exists with the - ** current key. The entry is unique if (1) any column is NULL - ** or (2) the next entry has a different key */ - if( IsUniqueIndex(pIdx) ){ - int uniqOk = sqlite3VdbeMakeLabel(v); - int jmp6; - int kk; - for(kk=0; kknKeyCol; kk++){ - int iCol = pIdx->aiColumn[kk]; - assert( iCol!=XN_ROWID && iColnCol ); - if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; - sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); - VdbeCoverage(v); + if( !isQuick ){ /* Omit the remaining tests for quick_check */ + /* Validate index entries for the current row */ + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + int jmp2, jmp3, jmp4, jmp5; + int ckUniq = sqlite3VdbeMakeLabel(v); + if( pPk==pIdx ) continue; + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, + pPrior, r1); + pPrior = pIdx; + sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */ + /* Verify that an index entry exists for the current table row */ + jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, + pIdx->nColumn); VdbeCoverage(v); + sqlite3VdbeLoadString(v, 3, "row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " missing from index "); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp4 = integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, jmp2); + /* For UNIQUE indexes, verify that only one entry exists with the + ** current key. The entry is unique if (1) any column is NULL + ** or (2) the next entry has a different key */ + if( IsUniqueIndex(pIdx) ){ + int uniqOk = sqlite3VdbeMakeLabel(v); + int jmp6; + int kk; + for(kk=0; kknKeyCol; kk++){ + int iCol = pIdx->aiColumn[kk]; + assert( iCol!=XN_ROWID && iColnCol ); + if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; + sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); + VdbeCoverage(v); + } + jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); + sqlite3VdbeGoto(v, uniqOk); + sqlite3VdbeJumpHere(v, jmp6); + sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, + pIdx->nKeyCol); VdbeCoverage(v); + sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); + sqlite3VdbeGoto(v, jmp5); + sqlite3VdbeResolveLabel(v, uniqOk); } - jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); - sqlite3VdbeGoto(v, uniqOk); - sqlite3VdbeJumpHere(v, jmp6); - sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, - pIdx->nKeyCol); VdbeCoverage(v); - sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); - sqlite3VdbeGoto(v, jmp5); - sqlite3VdbeResolveLabel(v, uniqOk); + sqlite3VdbeJumpHere(v, jmp4); + sqlite3ResolvePartIdxLabel(pParse, jmp3); } - sqlite3VdbeJumpHere(v, jmp4); - sqlite3ResolvePartIdxLabel(pParse, jmp3); } sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); sqlite3VdbeJumpHere(v, loopTop-1); @@ -1668,9 +1667,9 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeLoadString(v, 3, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); - integrityCheckResultRow(v, 7); + sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); + integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); } } @@ -1684,6 +1683,9 @@ void sqlite3Pragma( { OP_IfNotZero, 1, 4, 0}, /* 1 */ { OP_String8, 0, 3, 0}, /* 2 */ { OP_ResultRow, 3, 1, 0}, /* 3 */ + { OP_Halt, 0, 0, 0}, /* 4 */ + { OP_String8, 0, 3, 0}, /* 5 */ + { OP_Goto, 0, 3, 0}, /* 6 */ }; VdbeOp *aOp; @@ -1692,7 +1694,10 @@ void sqlite3Pragma( aOp[0].p2 = 1-mxErr; aOp[2].p4type = P4_STATIC; aOp[2].p4.z = "ok"; + aOp[5].p4type = P4_STATIC; + aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT); } + sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2); } } break; @@ -2212,26 +2217,25 @@ static int pragmaVtabConnect( UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x"); + sqlite3_str_appendall(&acc, "CREATE TABLE x"); for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ - sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]); + sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]); cSep = ','; } if( i==0 ){ - sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName); - cSep = ','; + sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); i++; } j = 0; if( pPragma->mPragFlg & PragFlg_Result1 ){ - sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN"); + sqlite3_str_appendall(&acc, ",arg HIDDEN"); j++; } if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ - sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN"); + sqlite3_str_appendall(&acc, ",schema HIDDEN"); j++; } - sqlite3StrAccumAppend(&acc, ")", 1); + sqlite3_str_append(&acc, ")", 1); sqlite3StrAccumFinish(&acc); assert( strlen(zBuf) < sizeof(zBuf)-1 ); rc = sqlite3_declare_vtab(db, zBuf); @@ -2383,13 +2387,13 @@ static int pragmaVtabFilter( } } sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); - sqlite3StrAccumAppendAll(&acc, "PRAGMA "); + sqlite3_str_appendall(&acc, "PRAGMA "); if( pCsr->azArg[1] ){ - sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]); + sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]); } - sqlite3StrAccumAppendAll(&acc, pTab->pName->zName); + sqlite3_str_appendall(&acc, pTab->pName->zName); if( pCsr->azArg[0] ){ - sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]); + sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]); } zSql = sqlite3StrAccumFinish(&acc); if( zSql==0 ) return SQLITE_NOMEM; diff --git a/src/pragma.h b/src/pragma.h index c9ece2dc87..3d1ba4f341 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -68,58 +68,57 @@ ** result column is different from the name of the pragma */ static const char *const pragCName[] = { - /* 0 */ "cache_size", /* Used by: default_cache_size */ - /* 1 */ "cid", /* Used by: table_info */ - /* 2 */ "name", - /* 3 */ "type", - /* 4 */ "notnull", - /* 5 */ "dflt_value", - /* 6 */ "pk", - /* 7 */ "tbl", /* Used by: stats */ - /* 8 */ "idx", - /* 9 */ "wdth", - /* 10 */ "hght", - /* 11 */ "flgs", - /* 12 */ "seqno", /* Used by: index_info */ - /* 13 */ "cid", - /* 14 */ "name", + /* 0 */ "id", /* Used by: foreign_key_list */ + /* 1 */ "seq", + /* 2 */ "table", + /* 3 */ "from", + /* 4 */ "to", + /* 5 */ "on_update", + /* 6 */ "on_delete", + /* 7 */ "match", + /* 8 */ "cid", /* Used by: table_xinfo */ + /* 9 */ "name", + /* 10 */ "type", + /* 11 */ "notnull", + /* 12 */ "dflt_value", + /* 13 */ "pk", + /* 14 */ "hidden", + /* table_info reuses 8 */ /* 15 */ "seqno", /* Used by: index_xinfo */ /* 16 */ "cid", /* 17 */ "name", /* 18 */ "desc", /* 19 */ "coll", /* 20 */ "key", - /* 21 */ "seq", /* Used by: index_list */ - /* 22 */ "name", - /* 23 */ "unique", - /* 24 */ "origin", - /* 25 */ "partial", - /* 26 */ "seq", /* Used by: database_list */ + /* 21 */ "tbl", /* Used by: stats */ + /* 22 */ "idx", + /* 23 */ "wdth", + /* 24 */ "hght", + /* 25 */ "flgs", + /* 26 */ "seq", /* Used by: index_list */ /* 27 */ "name", - /* 28 */ "file", - /* 29 */ "name", /* Used by: function_list */ - /* 30 */ "builtin", - /* 31 */ "name", /* Used by: module_list pragma_list */ - /* 32 */ "seq", /* Used by: collation_list */ - /* 33 */ "name", - /* 34 */ "id", /* Used by: foreign_key_list */ - /* 35 */ "seq", - /* 36 */ "table", - /* 37 */ "from", - /* 38 */ "to", - /* 39 */ "on_update", - /* 40 */ "on_delete", - /* 41 */ "match", - /* 42 */ "table", /* Used by: foreign_key_check */ - /* 43 */ "rowid", - /* 44 */ "parent", - /* 45 */ "fkid", - /* 46 */ "busy", /* Used by: wal_checkpoint */ - /* 47 */ "log", - /* 48 */ "checkpointed", - /* 49 */ "timeout", /* Used by: busy_timeout */ - /* 50 */ "database", /* Used by: lock_status */ - /* 51 */ "status", + /* 28 */ "unique", + /* 29 */ "origin", + /* 30 */ "partial", + /* 31 */ "table", /* Used by: foreign_key_check */ + /* 32 */ "rowid", + /* 33 */ "parent", + /* 34 */ "fkid", + /* index_info reuses 15 */ + /* 35 */ "seq", /* Used by: database_list */ + /* 36 */ "name", + /* 37 */ "file", + /* 38 */ "busy", /* Used by: wal_checkpoint */ + /* 39 */ "log", + /* 40 */ "checkpointed", + /* 41 */ "name", /* Used by: function_list */ + /* 42 */ "builtin", + /* collation_list reuses 26 */ + /* 43 */ "database", /* Used by: lock_status */ + /* 44 */ "status", + /* 45 */ "cache_size", /* Used by: default_cache_size */ + /* module_list pragma_list reuses 9 */ + /* 46 */ "timeout", /* Used by: busy_timeout */ }; /* Definitions of all built-in pragmas */ @@ -165,7 +164,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 49, 1, + /* ColNames: */ 46, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", @@ -202,7 +201,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 32, 2, + /* ColNames: */ 26, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) @@ -237,14 +236,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 26, 3, + /* ColNames: */ 35, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, - /* ColNames: */ 0, 1, + /* ColNames: */ 45, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -274,14 +273,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 42, 4, + /* ColNames: */ 31, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) {/* zName: */ "foreign_key_list", /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 34, 8, + /* ColNames: */ 0, 8, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -317,7 +316,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 29, 2, + /* ColNames: */ 41, 2, /* iArg: */ 0 }, #endif #endif @@ -353,12 +352,12 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 12, 3, + /* ColNames: */ 15, 3, /* iArg: */ 0 }, {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 21, 5, + /* ColNames: */ 26, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, @@ -393,6 +392,11 @@ static const PragmaName aPragmaName[] = { /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "legacy_alter_table", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_LegacyAlter }, {/* zName: */ "legacy_file_format", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, @@ -410,7 +414,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 50, 2, + /* ColNames: */ 43, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -436,7 +440,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "module_list", /* ePragTyp: */ PragTyp_MODULE_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 31, 1, + /* ColNames: */ 9, 1, /* iArg: */ 0 }, #endif #endif @@ -469,7 +473,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "pragma_list", /* ePragTyp: */ PragTyp_PRAGMA_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 31, 1, + /* ColNames: */ 9, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -556,7 +560,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, - /* ColNames: */ 7, 5, + /* ColNames: */ 21, 5, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -570,8 +574,13 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "table_info", /* ePragTyp: */ PragTyp_TABLE_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 1, 6, + /* ColNames: */ 8, 6, /* iArg: */ 0 }, + {/* zName: */ "table_xinfo", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 8, 7, + /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "temp_store", @@ -635,7 +644,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 46, 3, + /* ColNames: */ 38, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -646,4 +655,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema }, #endif }; -/* Number of pragmas: 60 on by default, 77 total. */ +/* Number of pragmas: 62 on by default, 79 total. */ diff --git a/src/prepare.c b/src/prepare.c index b0e1d0bce7..f8f0623f70 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -25,15 +25,23 @@ static void corruptSchema( const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; - if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){ + if( db->mallocFailed ){ + pData->rc = SQLITE_NOMEM_BKPT; + }else if( pData->pzErrMsg[0]!=0 ){ + /* A error message has already been generated. Do not overwrite it */ + }else if( pData->mInitFlags & INITFLAG_AlterTable ){ + *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); + pData->rc = SQLITE_ERROR; + }else if( db->flags & SQLITE_WriteSchema ){ + pData->rc = SQLITE_CORRUPT_BKPT; + }else{ char *z; if( zObj==0 ) zObj = "?"; z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); - if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); - sqlite3DbFree(db, *pData->pzErrMsg); + if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); *pData->pzErrMsg = z; + pData->rc = SQLITE_CORRUPT_BKPT; } - pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT; } /* @@ -105,7 +113,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = saved_iDb; - assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); + /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */ if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); @@ -162,7 +170,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ -static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ +int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ int rc; int i; #ifndef SQLITE_OMIT_DEPRECATED @@ -175,11 +183,14 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ const char *zMasterName; int openedTransaction = 0; + assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDbnDb ); assert( db->aDb[iDb].pSchema ); assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + db->init.busy = 1; + /* Construct the in-memory representation schema tables (sqlite_master or ** sqlite_temp_master) by invoking the parser directly. The appropriate ** table name will be inserted automatically by the parser so we can just @@ -188,12 +199,13 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ azArg[0] = zMasterName = SCHEMA_TABLE(iDb); azArg[1] = "1"; azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text," - "rootpage integer,sql text)"; + "rootpage int,sql text)"; azArg[3] = 0; initData.db = db; initData.iDb = iDb; initData.rc = SQLITE_OK; initData.pzErrMsg = pzErrMsg; + initData.mInitFlags = mFlags; sqlite3InitCallback(&initData, 3, (char **)azArg, 0); if( initData.rc ){ rc = initData.rc; @@ -204,10 +216,10 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ - DbSetProperty(db, 1, DB_SchemaLoaded); - } - return SQLITE_OK; + assert( iDb==1 ); + DbSetProperty(db, 1, DB_SchemaLoaded); + rc = SQLITE_OK; + goto error_out; } /* If there is not already a read-only (or read-write) transaction opened @@ -215,7 +227,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** will be closed before this function returns. */ sqlite3BtreeEnter(pDb->pBt); if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ - rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); goto initone_error_out; @@ -243,6 +255,9 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ for(i=0; ipBt, i+1, (u32 *)&meta[i]); } + if( (db->flags & SQLITE_ResetDatabase)!=0 ){ + memset(meta, 0, sizeof(meta)); + } pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; /* If opening a non-empty database, check the text encoding. For the @@ -370,9 +385,13 @@ initone_error_out: sqlite3BtreeLeave(pDb->pBt); error_out: - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - sqlite3OomFault(db); + if( rc ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + } + sqlite3ResetOneSchema(db, iDb); } + db->init.busy = 0; return rc; } @@ -393,37 +412,25 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ assert( sqlite3_mutex_held(db->mutex) ); assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); assert( db->init.busy==0 ); - rc = SQLITE_OK; - db->init.busy = 1; ENC(db) = SCHEMA_ENC(db); - for(i=0; rc==SQLITE_OK && inDb; i++){ - if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; - rc = sqlite3InitOne(db, i, pzErrMsg); - if( rc ){ - sqlite3ResetOneSchema(db, i); + assert( db->nDb>0 ); + /* Do the main schema first */ + if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, 0, pzErrMsg, 0); + if( rc ) return rc; + } + /* All other schemas after the main schema. The "temp" schema must be last */ + for(i=db->nDb-1; i>0; i--){ + assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); + if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, i, pzErrMsg, 0); + if( rc ) return rc; } } - - /* Once all the other databases have been initialized, load the schema - ** for the TEMP database. This is loaded last, as the TEMP database - ** schema may contain references to objects in other databases. - */ -#ifndef SQLITE_OMIT_TEMPDB - assert( db->nDb>1 ); - if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, 1, pzErrMsg); - if( rc ){ - sqlite3ResetOneSchema(db, 1); - } - } -#endif - - db->init.busy = 0; - if( rc==SQLITE_OK && commit_internal ){ + if( commit_internal ){ sqlite3CommitInternalChanges(db); } - - return rc; + return SQLITE_OK; } /* @@ -436,10 +443,12 @@ int sqlite3ReadSchema(Parse *pParse){ assert( sqlite3_mutex_held(db->mutex) ); if( !db->init.busy ){ rc = sqlite3Init(db, &pParse->zErrMsg); - } - if( rc!=SQLITE_OK ){ - pParse->rc = rc; - pParse->nErr++; + if( rc!=SQLITE_OK ){ + pParse->rc = rc; + pParse->nErr++; + }else if( db->noSharedCache ){ + db->mDbFlags |= DBFLAG_SchemaKnownOk; + } } return rc; } @@ -467,7 +476,7 @@ static void schemaIsValid(Parse *pParse){ ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ if( !sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); } @@ -514,7 +523,8 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ */ assert( sqlite3_mutex_held(db->mutex) ); if( pSchema ){ - for(i=0; ALWAYS(inDb); i++){ + for(i=0; 1; i++){ + assert( inDb ); if( db->aDb[i].pSchema==pSchema ){ break; } @@ -649,7 +659,7 @@ static int sqlite3Prepare( if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ static const char * const azColName[] = { "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", - "selectid", "order", "from", "detail" + "id", "parent", "notused", "detail" }; int iFirst, mx; if( sParse.explain==2 ){ @@ -695,8 +705,6 @@ static int sqlite3Prepare( end_prepare: sqlite3ParserReset(&sParse); - rc = sqlite3ApiExit(db, rc); - assert( (rc&db->errMask)==rc ); return rc; } static int sqlite3LockAndPrepare( @@ -709,6 +717,7 @@ static int sqlite3LockAndPrepare( const char **pzTail /* OUT: End of parsed string */ ){ int rc; + int cnt = 0; #ifdef SQLITE_ENABLE_API_ARMOR if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; @@ -719,14 +728,18 @@ static int sqlite3LockAndPrepare( } sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); - rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); - if( rc==SQLITE_SCHEMA ){ - sqlite3_finalize(*ppStmt); + do{ + /* Make multiple attempts to compile the SQL, until it either succeeds + ** or encounters a permanent error. A schema problem after one schema + ** reset is considered a permanent error. */ rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); - } + assert( rc==SQLITE_OK || *ppStmt==0 ); + }while( rc==SQLITE_ERROR_RETRY + || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) ); sqlite3BtreeLeaveAll(db); + rc = sqlite3ApiExit(db, rc); + assert( (rc&db->errMask)==rc ); sqlite3_mutex_leave(db->mutex); - assert( rc==SQLITE_OK || *ppStmt==0 ); return rc; } diff --git a/src/printf.c b/src/printf.c index a14e658875..7bce83f3e2 100644 --- a/src/printf.c +++ b/src/printf.c @@ -134,7 +134,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ ** Set the StrAccum object to an error mode. */ static void setStrAccumError(StrAccum *p, u8 eError){ - assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG ); + assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG ); p->accError = eError; p->nAlloc = 0; } @@ -168,8 +168,8 @@ static char *getTextArg(PrintfArguments *p){ /* ** Render a string given by "fmt" into the StrAccum object. */ -void sqlite3VXPrintf( - StrAccum *pAccum, /* Accumulate results here */ +void sqlite3_str_vappendf( + sqlite3_str *pAccum, /* Accumulate results here */ const char *fmt, /* Format string */ va_list ap /* arguments */ ){ @@ -206,6 +206,11 @@ void sqlite3VXPrintf( PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ char buf[etBUFSIZE]; /* Conversion buffer */ + /* pAccum never starts out with an empty buffer that was obtained from + ** malloc(). This precondition is required by the mprintf("%z...") + ** optimization. */ + assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); + bufpt = 0; if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){ pArgList = va_arg(ap, PrintfArguments*); @@ -221,11 +226,11 @@ void sqlite3VXPrintf( #else do{ fmt++; }while( *fmt && *fmt != '%' ); #endif - sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); + sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); if( *fmt==0 ) break; } if( (c=(*++fmt))==0 ){ - sqlite3StrAccumAppend(pAccum, "%", 1); + sqlite3_str_append(pAccum, "%", 1); break; } /* Find out what flags are present */ @@ -403,7 +408,7 @@ void sqlite3VXPrintf( u64 n = (u64)precision + 10 + precision/3; zOut = zExtra = sqlite3Malloc( n ); if( zOut==0 ){ - setStrAccumError(pAccum, STRACCUM_NOMEM); + setStrAccumError(pAccum, SQLITE_NOMEM); return; } nOut = (int)n; @@ -528,7 +533,7 @@ void sqlite3VXPrintf( bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); if( bufpt==0 ){ - setStrAccumError(pAccum, STRACCUM_NOMEM); + setStrAccumError(pAccum, SQLITE_NOMEM); return; } } @@ -624,22 +629,52 @@ void sqlite3VXPrintf( case etCHARX: if( bArgList ){ bufpt = getTextArg(pArgList); - c = bufpt ? bufpt[0] : 0; + length = 1; + if( bufpt ){ + buf[0] = c = *(bufpt++); + if( (c&0xc0)==0xc0 ){ + while( length<4 && (bufpt[0]&0xc0)==0x80 ){ + buf[length++] = *(bufpt++); + } + } + }else{ + buf[0] = 0; + } }else{ - c = va_arg(ap,int); + unsigned int ch = va_arg(ap,unsigned int); + if( ch<0x00080 ){ + buf[0] = ch & 0xff; + length = 1; + }else if( ch<0x00800 ){ + buf[0] = 0xc0 + (u8)((ch>>6)&0x1f); + buf[1] = 0x80 + (u8)(ch & 0x3f); + length = 2; + }else if( ch<0x10000 ){ + buf[0] = 0xe0 + (u8)((ch>>12)&0x0f); + buf[1] = 0x80 + (u8)((ch>>6) & 0x3f); + buf[2] = 0x80 + (u8)(ch & 0x3f); + length = 3; + }else{ + buf[0] = 0xf0 + (u8)((ch>>18) & 0x07); + buf[1] = 0x80 + (u8)((ch>>12) & 0x3f); + buf[2] = 0x80 + (u8)((ch>>6) & 0x3f); + buf[3] = 0x80 + (u8)(ch & 0x3f); + length = 4; + } } if( precision>1 ){ width -= precision-1; if( width>1 && !flag_leftjustify ){ - sqlite3AppendChar(pAccum, width-1, ' '); + sqlite3_str_appendchar(pAccum, width-1, ' '); width = 0; } - sqlite3AppendChar(pAccum, precision-1, c); + while( precision-- > 1 ){ + sqlite3_str_append(pAccum, buf, length); + } } - length = 1; - buf[0] = c; bufpt = buf; - break; + flag_altform2 = 1; + goto adjust_width_for_utf8; case etSTRING: case etDYNSTRING: if( bArgList ){ @@ -651,17 +686,50 @@ void sqlite3VXPrintf( if( bufpt==0 ){ bufpt = ""; }else if( xtype==etDYNSTRING ){ + if( pAccum->nChar==0 + && pAccum->mxAlloc + && width==0 + && precision<0 + && pAccum->accError==0 + ){ + /* Special optimization for sqlite3_mprintf("%z..."): + ** Extend an existing memory allocation rather than creating + ** a new one. */ + assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); + pAccum->zText = bufpt; + pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt); + pAccum->nChar = 0x7fffffff & (int)strlen(bufpt); + pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED; + length = 0; + break; + } zExtra = bufpt; } if( precision>=0 ){ - for(length=0; length 0 && z[0] ){ + SQLITE_SKIP_UTF8(z); + } + length = (int)(z - (unsigned char*)bufpt); + }else{ + for(length=0; length0 ){ + /* Adjust width to account for extra bytes in UTF-8 characters */ + int ii = length - 1; + while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; } break; - case etSQLESCAPE: /* Escape ' characters */ - case etSQLESCAPE2: /* Escape ' and enclose in '...' */ - case etSQLESCAPE3: { /* Escape " characters */ + case etSQLESCAPE: /* %q: Escape ' characters */ + case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ + case etSQLESCAPE3: { /* %w: Escape " characters */ int i, j, k, n, isnull; int needQuote; char ch; @@ -675,16 +743,24 @@ void sqlite3VXPrintf( } isnull = escarg==0; if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); + /* For %q, %Q, and %w, the precision is the number of byte (or + ** characters if the ! flags is present) to use from the input. + ** Because of the extra quoting characters inserted, the number + ** of output characters may be larger than the precision. + */ k = precision; for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){ if( ch==q ) n++; + if( flag_altform2 && (ch&0xc0)==0xc0 ){ + while( (escarg[i+1]&0xc0)==0x80 ){ i++; } + } } needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 3; if( n>etBUFSIZE ){ bufpt = zExtra = sqlite3Malloc( n ); if( bufpt==0 ){ - setStrAccumError(pAccum, STRACCUM_NOMEM); + setStrAccumError(pAccum, SQLITE_NOMEM); return; } }else{ @@ -700,10 +776,7 @@ void sqlite3VXPrintf( if( needQuote ) bufpt[j++] = q; bufpt[j] = 0; length = j; - /* The precision in %q and %Q means how many input characters to - ** consume, not the length of the output... - ** if( precision>=0 && precisionn ){ - sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); + sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); } length = width = 0; break; @@ -727,10 +800,10 @@ void sqlite3VXPrintf( assert( bArgList==0 ); assert( k>=0 && knSrc ); if( pItem->zDatabase ){ - sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); - sqlite3StrAccumAppend(pAccum, ".", 1); + sqlite3_str_appendall(pAccum, pItem->zDatabase); + sqlite3_str_append(pAccum, ".", 1); } - sqlite3StrAccumAppendAll(pAccum, pItem->zName); + sqlite3_str_appendall(pAccum, pItem->zName); length = width = 0; break; } @@ -742,15 +815,18 @@ void sqlite3VXPrintf( /* ** The text of the conversion is pointed to by "bufpt" and is ** "length" characters long. The field width is "width". Do - ** the output. + ** the output. Both length and width are in bytes, not characters, + ** at this point. If the "!" flag was present on string conversions + ** indicating that width and precision should be expressed in characters, + ** then the values have been translated prior to reaching this point. */ width -= length; if( width>0 ){ - if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); - sqlite3StrAccumAppend(pAccum, bufpt, length); - if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); + if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); + sqlite3_str_append(pAccum, bufpt, length); + if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); }else{ - sqlite3StrAccumAppend(pAccum, bufpt, length); + sqlite3_str_append(pAccum, bufpt, length); } if( zExtra ){ @@ -771,18 +847,17 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ char *zNew; assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ if( p->accError ){ - testcase(p->accError==STRACCUM_TOOBIG); - testcase(p->accError==STRACCUM_NOMEM); + testcase(p->accError==SQLITE_TOOBIG); + testcase(p->accError==SQLITE_NOMEM); return 0; } if( p->mxAlloc==0 ){ N = p->nAlloc - p->nChar - 1; - setStrAccumError(p, STRACCUM_TOOBIG); + setStrAccumError(p, SQLITE_TOOBIG); return N; }else{ char *zOld = isMalloced(p) ? p->zText : 0; i64 szNew = p->nChar; - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); szNew += N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, @@ -790,8 +865,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ szNew += p->nChar; } if( szNew > p->mxAlloc ){ - sqlite3StrAccumReset(p); - setStrAccumError(p, STRACCUM_TOOBIG); + sqlite3_str_reset(p); + setStrAccumError(p, SQLITE_TOOBIG); return 0; }else{ p->nAlloc = (int)szNew; @@ -808,8 +883,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ p->nAlloc = sqlite3DbMallocSize(p->db, zNew); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ - sqlite3StrAccumReset(p); - setStrAccumError(p, STRACCUM_NOMEM); + sqlite3_str_reset(p); + setStrAccumError(p, SQLITE_NOMEM); return 0; } } @@ -819,12 +894,11 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ /* ** Append N copies of character c to the given string buffer. */ -void sqlite3AppendChar(StrAccum *p, int N, char c){ +void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){ testcase( p->nChar + (i64)N > 0x7fffffff ); if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ return; } - assert( (p->zText==p->zBase)==!isMalloced(p) ); while( (N--)>0 ) p->zText[p->nChar++] = c; } @@ -832,9 +906,9 @@ void sqlite3AppendChar(StrAccum *p, int N, char c){ ** The StrAccum "p" is not large enough to accept N new bytes of z[]. ** So enlarge if first, then do the append. ** -** This is a helper routine to sqlite3StrAccumAppend() that does special-case +** This is a helper routine to sqlite3_str_append() that does special-case ** work (enlarging the buffer) using tail recursion, so that the -** sqlite3StrAccumAppend() routine can use fast calling semantics. +** sqlite3_str_append() routine can use fast calling semantics. */ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ N = sqlite3StrAccumEnlarge(p, N); @@ -842,14 +916,13 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ memcpy(&p->zText[p->nChar], z, N); p->nChar += N; } - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); } /* ** Append N bytes of text from z to the StrAccum object. Increase the ** size of the memory allocation for StrAccum if necessary. */ -void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ +void sqlite3_str_append(sqlite3_str *p, const char *z, int N){ assert( z!=0 || N==0 ); assert( p->zText!=0 || p->nChar==0 || p->accError ); assert( N>=0 ); @@ -866,8 +939,8 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ /* ** Append the complete text of zero-terminated string z[] to the p string. */ -void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ - sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); +void sqlite3_str_appendall(sqlite3_str *p, const char *z){ + sqlite3_str_append(p, z, sqlite3Strlen30(z)); } @@ -877,19 +950,20 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ ** pointer if any kind of error was encountered. */ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ + char *zText; assert( p->mxAlloc>0 && !isMalloced(p) ); - p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); - if( p->zText ){ - memcpy(p->zText, p->zBase, p->nChar+1); + zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + if( zText ){ + memcpy(zText, p->zText, p->nChar+1); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ - setStrAccumError(p, STRACCUM_NOMEM); + setStrAccumError(p, SQLITE_NOMEM); } - return p->zText; + p->zText = zText; + return zText; } char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ - assert( (p->zText==p->zBase)==!isMalloced(p) ); p->zText[p->nChar] = 0; if( p->mxAlloc>0 && !isMalloced(p) ){ return strAccumFinishRealloc(p); @@ -898,15 +972,56 @@ char *sqlite3StrAccumFinish(StrAccum *p){ return p->zText; } +/* +** This singleton is an sqlite3_str object that is returned if +** sqlite3_malloc() fails to provide space for a real one. This +** sqlite3_str object accepts no new text and always returns +** an SQLITE_NOMEM error. +*/ +static sqlite3_str sqlite3OomStr = { + 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 +}; + +/* Finalize a string created using sqlite3_str_new(). +*/ +char *sqlite3_str_finish(sqlite3_str *p){ + char *z; + if( p!=0 && p!=&sqlite3OomStr ){ + z = sqlite3StrAccumFinish(p); + sqlite3_free(p); + }else{ + z = 0; + } + return z; +} + +/* Return any error code associated with p */ +int sqlite3_str_errcode(sqlite3_str *p){ + return p ? p->accError : SQLITE_NOMEM; +} + +/* Return the current length of p in bytes */ +int sqlite3_str_length(sqlite3_str *p){ + return p ? p->nChar : 0; +} + +/* Return the current value for p */ +char *sqlite3_str_value(sqlite3_str *p){ + if( p==0 || p->nChar==0 ) return 0; + p->zText[p->nChar] = 0; + return p->zText; +} + /* ** Reset an StrAccum string. Reclaim all malloced memory. */ -void sqlite3StrAccumReset(StrAccum *p){ - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); +void sqlite3_str_reset(StrAccum *p){ if( isMalloced(p) ){ sqlite3DbFree(p->db, p->zText); p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; } + p->nAlloc = 0; + p->nChar = 0; p->zText = 0; } @@ -925,15 +1040,27 @@ void sqlite3StrAccumReset(StrAccum *p){ ** allocations will ever occur. */ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ - p->zText = p->zBase = zBase; + p->zText = zBase; p->db = db; - p->nChar = 0; p->nAlloc = n; p->mxAlloc = mx; + p->nChar = 0; p->accError = 0; p->printfFlags = 0; } +/* Allocate and initialize a new dynamic string object */ +sqlite3_str *sqlite3_str_new(sqlite3 *db){ + sqlite3_str *p = sqlite3_malloc64(sizeof(*p)); + if( p ){ + sqlite3StrAccumInit(p, 0, 0, 0, + db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); + }else{ + p = &sqlite3OomStr; + } + return p; +} + /* ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. @@ -946,9 +1073,9 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); acc.printfFlags = SQLITE_PRINTF_INTERNAL; - sqlite3VXPrintf(&acc, zFormat, ap); + sqlite3_str_vappendf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); - if( acc.accError==STRACCUM_NOMEM ){ + if( acc.accError==SQLITE_NOMEM ){ sqlite3OomFault(db); } return z; @@ -986,7 +1113,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){ if( sqlite3_initialize() ) return 0; #endif sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); - sqlite3VXPrintf(&acc, zFormat, ap); + sqlite3_str_vappendf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); return z; } @@ -1031,7 +1158,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ } #endif sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); - sqlite3VXPrintf(&acc, zFormat, ap); + sqlite3_str_vappendf(&acc, zFormat, ap); zBuf[acc.nChar] = 0; return zBuf; } @@ -1053,7 +1180,7 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ ** allocate memory because it might be called while the memory allocator ** mutex is held. ** -** sqlite3VXPrintf() might ask for *temporary* memory allocations for +** sqlite3_str_vappendf() might ask for *temporary* memory allocations for ** certain format characters (%q) or for very large precisions or widths. ** Care must be taken that any sqlite3_log() calls that occur while the ** memory mutex is held do not use these mechanisms. @@ -1063,7 +1190,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); - sqlite3VXPrintf(&acc, zFormat, ap); + sqlite3_str_vappendf(&acc, zFormat, ap); sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, sqlite3StrAccumFinish(&acc)); } @@ -1092,22 +1219,29 @@ void sqlite3DebugPrintf(const char *zFormat, ...){ char zBuf[500]; sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); va_start(ap,zFormat); - sqlite3VXPrintf(&acc, zFormat, ap); + sqlite3_str_vappendf(&acc, zFormat, ap); va_end(ap); sqlite3StrAccumFinish(&acc); +#ifdef SQLITE_OS_TRACE_PROC + { + extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf); + SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf)); + } +#else fprintf(stdout,"%s", zBuf); fflush(stdout); +#endif } #endif /* -** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument +** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. */ -void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ +void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ va_list ap; va_start(ap,zFormat); - sqlite3VXPrintf(p, zFormat, ap); + sqlite3_str_vappendf(p, zFormat, ap); va_end(ap); } diff --git a/src/resolve.c b/src/resolve.c index 78f37512a2..34a0515831 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -75,29 +75,31 @@ static void resolveAlias( assert( pOrig!=0 ); db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); - if( pDup==0 ) return; - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); - if( pExpr->op==TK_COLLATE ){ - pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); - } - ExprSetProperty(pDup, EP_Alias); + if( pDup!=0 ){ + if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); + if( pExpr->op==TK_COLLATE ){ + pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); + } + ExprSetProperty(pDup, EP_Alias); - /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This - ** prevents ExprDelete() from deleting the Expr structure itself, - ** allowing it to be repopulated by the memcpy() on the following line. - ** The pExpr->u.zToken might point into memory that will be freed by the - ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to - ** make a copy of the token before doing the sqlite3DbFree(). - */ - ExprSetProperty(pExpr, EP_Static); - sqlite3ExprDelete(db, pExpr); - memcpy(pExpr, pDup, sizeof(*pExpr)); - if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ - assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); - pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); - pExpr->flags |= EP_MemToken; + /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This + ** prevents ExprDelete() from deleting the Expr structure itself, + ** allowing it to be repopulated by the memcpy() on the following line. + ** The pExpr->u.zToken might point into memory that will be freed by the + ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to + ** make a copy of the token before doing the sqlite3DbFree(). + */ + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(db, pExpr); + memcpy(pExpr, pDup, sizeof(*pExpr)); + if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ + assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); + pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); + pExpr->flags |= EP_MemToken; + } + sqlite3DbFree(db, pDup); } - sqlite3DbFree(db, pDup); + ExprSetProperty(pExpr, EP_Alias); } @@ -157,7 +159,7 @@ int sqlite3MatchSpanName( ** (even if X is implied). ** pExpr->iTable Set to the cursor number for the table obtained ** from pSrcList. -** pExpr->pTab Points to the Table structure of X.Y (even if +** pExpr->y.pTab Points to the Table structure of X.Y (even if ** X and/or Y are implied.) ** pExpr->iColumn Set to the column number within the table. ** pExpr->op Set to TK_COLUMN. @@ -191,7 +193,7 @@ static int lookupName( struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ - int isTrigger = 0; /* True if resolved to a trigger column */ + int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ Table *pTab = 0; /* Table hold the row */ Column *pCol; /* A column of pTab */ @@ -201,7 +203,6 @@ static int lookupName( /* Initialize the node to no-match */ pExpr->iTable = -1; - pExpr->pTab = 0; ExprSetVVAProperty(pExpr, EP_NoReduce); /* Translate the schema name in zDb into a pointer to the corresponding @@ -262,6 +263,9 @@ static int lookupName( if( sqlite3StrICmp(zTabName, zTab)!=0 ){ continue; } + if( IN_RENAME_OBJECT && pItem->zAlias ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); + } } if( 0==(cntTab++) ){ pMatch = pItem; @@ -286,32 +290,45 @@ static int lookupName( } if( pMatch ){ pExpr->iTable = pMatch->iCursor; - pExpr->pTab = pMatch->pTab; + pExpr->y.pTab = pMatch->pTab; /* RIGHT JOIN not (yet) supported */ assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } - pSchema = pExpr->pTab->pSchema; + pSchema = pExpr->y.pTab->pSchema; } } /* if( pSrcList ) */ -#ifndef SQLITE_OMIT_TRIGGER +#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) /* If we have not already resolved the name, then maybe - ** it is a new.* or old.* trigger argument reference + ** it is a new.* or old.* trigger argument reference. Or + ** maybe it is an excluded.* from an upsert. */ - if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){ - int op = pParse->eTriggerOp; - assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); - if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ - pExpr->iTable = 1; - pTab = pParse->pTriggerTab; - }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ - pExpr->iTable = 0; - pTab = pParse->pTriggerTab; - }else{ - pTab = 0; + if( zDb==0 && zTab!=0 && cntTab==0 ){ + pTab = 0; +#ifndef SQLITE_OMIT_TRIGGER + if( pParse->pTriggerTab!=0 ){ + int op = pParse->eTriggerOp; + assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); + if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ + pExpr->iTable = 1; + pTab = pParse->pTriggerTab; + }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ + pExpr->iTable = 0; + pTab = pParse->pTriggerTab; + } } +#endif /* SQLITE_OMIT_TRIGGER */ +#ifndef SQLITE_OMIT_UPSERT + if( (pNC->ncFlags & NC_UUpsert)!=0 ){ + Upsert *pUpsert = pNC->uNC.pUpsert; + if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ + pTab = pUpsert->pUpsertSrc->a[0].pTab; + pExpr->iTable = 2; + } + } +#endif /* SQLITE_OMIT_UPSERT */ if( pTab ){ int iCol; @@ -331,24 +348,42 @@ static int lookupName( } if( iColnCol ){ cnt++; - if( iCol<0 ){ - pExpr->affinity = SQLITE_AFF_INTEGER; - }else if( pExpr->iTable==0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<iTable==2 ){ + testcase( iCol==(-1) ); + if( IN_RENAME_OBJECT ){ + pExpr->iColumn = iCol; + pExpr->y.pTab = pTab; + eNewExprOp = TK_COLUMN; + }else{ + pExpr->iTable = pNC->uNC.pUpsert->regData + iCol; + eNewExprOp = TK_REGISTER; + ExprSetProperty(pExpr, EP_Alias); + } + }else +#endif /* SQLITE_OMIT_UPSERT */ + { +#ifndef SQLITE_OMIT_TRIGGER + if( iCol<0 ){ + pExpr->affinity = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<y.pTab = pTab; + pExpr->iColumn = (i16)iCol; + eNewExprOp = TK_TRIGGER; +#endif /* SQLITE_OMIT_TRIGGER */ } - pExpr->iColumn = (i16)iCol; - pExpr->pTab = pTab; - isTrigger = 1; } } } -#endif /* !defined(SQLITE_OMIT_TRIGGER) */ +#endif /* !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) */ /* ** Perhaps the name is a reference to the ROWID @@ -383,10 +418,12 @@ static int lookupName( ** is supported for backwards compatibility only. Hence, we issue a warning ** on sqlite3_log() whenever the capability is used. */ - if( (pEList = pNC->pEList)!=0 - && zTab==0 + if( (pNC->ncFlags & NC_UEList)!=0 && cnt==0 + && zTab==0 ){ + pEList = pNC->uNC.pEList; + assert( pEList!=0 ); for(j=0; jnExpr; j++){ char *zAs = pEList->a[j].zName; if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ @@ -407,6 +444,9 @@ static int lookupName( cnt = 1; pMatch = 0; assert( zTab==0 && zDb==0 ); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + } goto lookupname_end; } } @@ -431,10 +471,16 @@ static int lookupName( ** Because no reference was made to outer contexts, the pNC->nRef ** fields are not changed in any context. */ - if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ - pExpr->op = TK_STRING; - pExpr->pTab = 0; - return WRC_Prune; + if( cnt==0 && zTab==0 ){ + assert( pExpr->op==TK_ID ); + if( ExprHasProperty(pExpr,EP_DblQuoted) ){ + pExpr->op = TK_STRING; + pExpr->y.pTab = 0; + return WRC_Prune; + } + if( sqlite3ExprIdToTrueFalse(pExpr) ){ + return WRC_Prune; + } } /* @@ -477,7 +523,7 @@ static int lookupName( pExpr->pLeft = 0; sqlite3ExprDelete(db, pExpr->pRight); pExpr->pRight = 0; - pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); + pExpr->op = eNewExprOp; ExprSetProperty(pExpr, EP_Leaf); lookupname_end: if( cnt==1 ){ @@ -507,9 +553,9 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ struct SrcList_item *pItem = &pSrc->a[iSrc]; - p->pTab = pItem->pTab; + p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; - if( p->pTab->iPKey==iCol ){ + if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; }else{ p->iColumn = (ynVar)iCol; @@ -596,9 +642,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ SrcList *pSrcList = pNC->pSrcList; struct SrcList_item *pItem; assert( pSrcList && pSrcList->nSrc==1 ); - pItem = pSrcList->a; + pItem = pSrcList->a; + assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 ); pExpr->op = TK_COLUMN; - pExpr->pTab = pItem->pTab; + pExpr->y.pTab = pItem->pTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn = -1; pExpr->affinity = SQLITE_AFF_INTEGER; @@ -627,17 +674,22 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zTable = 0; zColumn = pExpr->u.zToken; }else{ + Expr *pLeft = pExpr->pLeft; notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); pRight = pExpr->pRight; if( pRight->op==TK_ID ){ zDb = 0; - zTable = pExpr->pLeft->u.zToken; - zColumn = pRight->u.zToken; }else{ assert( pRight->op==TK_DOT ); - zDb = pExpr->pLeft->u.zToken; - zTable = pRight->pLeft->u.zToken; - zColumn = pRight->pRight->u.zToken; + zDb = pLeft->u.zToken; + pLeft = pRight->pLeft; + pRight = pRight->pRight; + } + zTable = pLeft->u.zToken; + zColumn = pRight->u.zToken; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); + sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); } } return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); @@ -720,40 +772,95 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ NC_IdxExpr|NC_PartIdx); } } - if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); - pNC->nErr++; - is_agg = 0; - }else if( no_such_func && pParse->db->init.busy==0 -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - && pParse->explain==0 + + if( 0==IN_RENAME_OBJECT ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX) + || (pDef->xValue==0 && pDef->xInverse==0) + || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) + ); + if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3ErrorMsg(pParse, + "%.*s() may not be used as a window function", nId, zId + ); + pNC->nErr++; + }else if( + (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) + || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin) + || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0) + ){ + const char *zType; + if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){ + zType = "window"; + }else{ + zType = "aggregate"; + } + sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); + pNC->nErr++; + is_agg = 0; + } +#else + if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ + sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId); + pNC->nErr++; + is_agg = 0; + } #endif - ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - pNC->nErr++; - }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); - pNC->nErr++; + else if( no_such_func && pParse->db->init.busy==0 +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + && pParse->explain==0 +#endif + ){ + sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + pNC->nErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", + nId, zId); + pNC->nErr++; + } + if( is_agg ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg); +#else + pNC->ncFlags &= ~NC_AllowAgg; +#endif + } } - if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; sqlite3WalkExprList(pWalker, pList); if( is_agg ){ - NameContext *pNC2 = pNC; - pExpr->op = TK_AGG_FUNCTION; - pExpr->op2 = 0; - while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ - pExpr->op2++; - pNC2 = pNC2->pNext; - } - assert( pDef!=0 ); - if( pNC2 ){ - assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); - testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); - pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pExpr->y.pWin ){ + Select *pSel = pNC->pWinSelect; + sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition); + sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy); + sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); + sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef); + if( 0==pSel->pWin + || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) + ){ + pExpr->y.pWin->pNextWin = pSel->pWin; + pSel->pWin = pExpr->y.pWin; + } + pNC->ncFlags |= NC_AllowWin; + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + NameContext *pNC2 = pNC; + pExpr->op = TK_AGG_FUNCTION; + pExpr->op2 = 0; + while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ + pExpr->op2++; + pNC2 = pNC2->pNext; + } + assert( pDef!=0 ); + if( pNC2 ){ + assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); + pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); + } + pNC->ncFlags |= NC_AllowAgg; } - pNC->ncFlags |= NC_AllowAgg; } /* FIX ME: Compute pExpr->affinity based on the expected return ** type of the function @@ -782,15 +889,30 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); break; } + case TK_IS: + case TK_ISNOT: { + Expr *pRight; + assert( !ExprHasProperty(pExpr, EP_Reduced) ); + /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", + ** and "x IS NOT FALSE". */ + if( (pRight = pExpr->pRight)->op==TK_ID ){ + int rc = resolveExprStep(pWalker, pRight); + if( rc==WRC_Abort ) return WRC_Abort; + if( pRight->op==TK_TRUEFALSE ){ + pExpr->op2 = pExpr->op; + pExpr->op = TK_TRUTH; + return WRC_Continue; + } + } + /* Fall thru */ + } case TK_BETWEEN: case TK_EQ: case TK_NE: case TK_LT: case TK_LE: case TK_GT: - case TK_GE: - case TK_IS: - case TK_ISNOT: { + case TK_GE: { int nLeft, nRight; if( pParse->db->mallocFailed ) break; assert( pExpr->pLeft!=0 ); @@ -893,8 +1015,8 @@ static int resolveOrderByTermToExprList( memset(&nc, 0, sizeof(nc)); nc.pParse = pParse; nc.pSrcList = pSelect->pSrc; - nc.pEList = pEList; - nc.ncFlags = NC_AllowAgg; + nc.uNC.pEList = pEList; + nc.ncFlags = NC_AllowAgg|NC_UEList; nc.nErr = 0; db = pParse->db; savedSuppErr = db->suppressErr; @@ -959,12 +1081,10 @@ static int resolveCompoundOrderBy( pOrderBy = pSelect->pOrderBy; if( pOrderBy==0 ) return 0; db = pParse->db; -#if SQLITE_MAX_COLUMN if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); return 1; } -#endif for(i=0; inExpr; i++){ pOrderBy->a[i].done = 0; } @@ -1056,12 +1176,10 @@ int sqlite3ResolveOrderGroupBy( struct ExprList_item *pItem; if( pOrderBy==0 || pParse->db->mallocFailed ) return 0; -#if SQLITE_MAX_COLUMN if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); return 1; } -#endif pEList = pSelect->pEList; assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ @@ -1143,6 +1261,19 @@ static int resolveOrderGroupBy( } for(j=0; jpEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pE, EP_WinFunc) ){ + /* Since this window function is being changed into a reference + ** to the same window function the result set, remove the instance + ** of this window function from the Select.pWin list. */ + Window **pp; + for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){ + if( *pp==pE->y.pWin ){ + *pp = (*pp)->pNextWin; + } + } + } +#endif pItem->u.x.iOrderByCol = j+1; } } @@ -1199,8 +1330,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ */ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; - if( sqlite3ResolveExprNames(&sNC, p->pLimit) || - sqlite3ResolveExprNames(&sNC, p->pOffset) ){ + sNC.pWinSelect = p; + if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){ return WRC_Abort; } @@ -1248,12 +1379,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. */ - sNC.ncFlags = NC_AllowAgg; + sNC.ncFlags = NC_AllowAgg|NC_AllowWin; sNC.pSrcList = p->pSrc; sNC.pNext = pOuterNC; /* Resolve names in the result set. */ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; + sNC.ncFlags &= ~NC_AllowWin; /* If there are no aggregate functions in the result-set, and no GROUP BY ** expression, do not allow aggregates in any of the other expressions. @@ -1282,7 +1414,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** Minor point: If this is the case, then the expression will be ** re-evaluated for each reference to it. */ - sNC.pEList = p->pEList; + assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 ); + sNC.uNC.pEList = p->pEList; + sNC.ncFlags |= NC_UEList; if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; @@ -1300,7 +1434,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** outer queries */ sNC.pNext = 0; - sNC.ncFlags |= NC_AllowAgg; + sNC.ncFlags |= NC_AllowAgg|NC_AllowWin; /* If this is a converted compound query, move the ORDER BY clause from ** the sub-query back to the parent query. At this point each term @@ -1331,6 +1465,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( db->mallocFailed ){ return WRC_Abort; } + sNC.ncFlags &= ~NC_AllowWin; /* Resolve the GROUP BY clause. At the same time, make sure ** the GROUP BY clause does not contain aggregate functions. @@ -1515,7 +1650,7 @@ void sqlite3ResolveSelfReference( Table *pTab, /* The table being referenced */ int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */ Expr *pExpr, /* Expression to resolve. May be NULL. */ - ExprList *pList /* Expression list to resolve. May be NUL. */ + ExprList *pList /* Expression list to resolve. May be NULL. */ ){ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ diff --git a/src/rowset.c b/src/rowset.c index aa81607b9f..703cf499bc 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -124,30 +124,23 @@ struct RowSet { #define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ /* -** Turn bulk memory into a RowSet object. N bytes of memory -** are available at pSpace. The db pointer is used as a memory context -** for any subsequent allocations that need to occur. -** Return a pointer to the new RowSet object. -** -** It must be the case that N is sufficient to make a Rowset. If not -** an assertion fault occurs. -** -** If N is larger than the minimum, use the surplus as an initial -** allocation of entries available to be filled. +** Allocate a RowSet object. Return NULL if a memory allocation +** error occurs. */ -RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ - RowSet *p; - assert( N >= ROUND8(sizeof(*p)) ); - p = pSpace; - p->pChunk = 0; - p->db = db; - p->pEntry = 0; - p->pLast = 0; - p->pForest = 0; - p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); - p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); - p->rsFlags = ROWSET_SORTED; - p->iBatch = 0; +RowSet *sqlite3RowSetInit(sqlite3 *db){ + RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p)); + if( p ){ + int N = sqlite3DbMallocSize(db, p); + p->pChunk = 0; + p->db = db; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); + p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); + p->rsFlags = ROWSET_SORTED; + p->iBatch = 0; + } return p; } @@ -156,7 +149,8 @@ RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ ** the RowSet has allocated over its lifetime. This routine is ** the destructor for the RowSet. */ -void sqlite3RowSetClear(RowSet *p){ +void sqlite3RowSetClear(void *pArg){ + RowSet *p = (RowSet*)pArg; struct RowSetChunk *pChunk, *pNextChunk; for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ pNextChunk = pChunk->pNextChunk; @@ -170,6 +164,16 @@ void sqlite3RowSetClear(RowSet *p){ p->rsFlags = ROWSET_SORTED; } +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +void sqlite3RowSetDelete(void *pArg){ + sqlite3RowSetClear(pArg); + sqlite3DbFree(((RowSet*)pArg)->db, pArg); +} + /* ** Allocate a new RowSetEntry object that is associated with the ** given RowSet. Return a pointer to the new and completely uninitialized diff --git a/src/select.c b/src/select.c index 255d729223..1d2cd1a969 100644 --- a/src/select.c +++ b/src/select.c @@ -21,8 +21,7 @@ /***/ int sqlite3SelectTrace = 0; # define SELECTTRACE(K,P,S,X) \ if(sqlite3SelectTrace&(K)) \ - sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\ - (S)->zSelName,(S)),\ + sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else # define SELECTTRACE(K,P,S,X) @@ -45,6 +44,20 @@ struct DistinctCtx { /* ** An instance of the following object is used to record information about ** the ORDER BY (or GROUP BY) clause of query is being coded. +** +** The aDefer[] array is used by the sorter-references optimization. For +** example, assuming there is no index that can be used for the ORDER BY, +** for the query: +** +** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10; +** +** it may be more efficient to add just the "a" values to the sorter, and +** retrieve the associated "bigblob" values directly from table t1 as the +** 10 smallest "a" values are extracted from the sorter. +** +** When the sorter-reference optimization is used, there is one entry in the +** aDefer[] array for each database table that may be read as values are +** extracted from the sorter. */ typedef struct SortCtx SortCtx; struct SortCtx { @@ -55,8 +68,17 @@ struct SortCtx { int labelBkOut; /* Start label for the block-output subroutine */ int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ int labelDone; /* Jump here when done, ex: LIMIT reached */ + int labelOBLopt; /* Jump here when sorter is full */ u8 sortFlags; /* Zero or more SORTFLAG_* bits */ - u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + u8 nDefer; /* Number of valid entries in aDefer[] */ + struct DeferredCsr { + Table *pTab; /* Table definition */ + int iCsr; /* Cursor number for table */ + int nKey; /* Number of PK columns for table pTab (>=1) */ + } aDefer[4]; +#endif + struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ }; #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ @@ -74,8 +96,12 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ sqlite3ExprDelete(db, p->pHaving); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); - sqlite3ExprDelete(db, p->pOffset); - if( p->pWith ) sqlite3WithDelete(db, p->pWith); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ + sqlite3WindowListDelete(db, p->pWinDefn); + } +#endif + if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; @@ -107,8 +133,7 @@ Select *sqlite3SelectNew( Expr *pHaving, /* the HAVING clause */ ExprList *pOrderBy, /* the ORDER BY clause */ u32 selFlags, /* Flag parameters, such as SF_Distinct */ - Expr *pLimit, /* LIMIT value. NULL means not used */ - Expr *pOffset /* OFFSET value. NULL means no offset */ + Expr *pLimit /* LIMIT value. NULL means not used */ ){ Select *pNew; Select standin; @@ -118,16 +143,15 @@ Select *sqlite3SelectNew( pNew = &standin; } if( pEList==0 ){ - pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0)); + pEList = sqlite3ExprListAppend(pParse, 0, + sqlite3Expr(pParse->db,TK_ASTERISK,0)); } pNew->pEList = pEList; pNew->op = TK_SELECT; pNew->selFlags = selFlags; pNew->iLimit = 0; pNew->iOffset = 0; -#if SELECTTRACE_ENABLED - pNew->zSelName[0] = 0; -#endif + pNew->selId = ++pParse->nSelect; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; @@ -140,9 +164,11 @@ Select *sqlite3SelectNew( pNew->pPrior = 0; pNew->pNext = 0; pNew->pLimit = pLimit; - pNew->pOffset = pOffset; pNew->pWith = 0; - assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = 0; +#endif if( pParse->db->mallocFailed ) { clearSelect(pParse->db, pNew, pNew!=&standin); pNew = 0; @@ -153,23 +179,12 @@ Select *sqlite3SelectNew( return pNew; } -#if SELECTTRACE_ENABLED -/* -** Set the name of a Select object -*/ -void sqlite3SelectSetName(Select *p, const char *zName){ - if( p && zName ){ - sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName); - } -} -#endif - /* ** Delete the given Select structure and all of its substructures. */ void sqlite3SelectDelete(sqlite3 *db, Select *p){ - if( p ) clearSelect(db, p, 1); + if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } /* @@ -386,6 +401,29 @@ static void setJoinExpr(Expr *p, int iTable){ } } +/* Undo the work of setJoinExpr(). In the expression tree p, convert every +** term that is marked with EP_FromJoin and iRightJoinTable==iTable into +** an ordinary term that omits the EP_FromJoin mark. +** +** This happens when a LEFT JOIN is simplified into an ordinary JOIN. +*/ +static void unsetJoinExpr(Expr *p, int iTable){ + while( p ){ + if( ExprHasProperty(p, EP_FromJoin) + && (iTable<0 || p->iRightJoinTable==iTable) ){ + ExprClearProperty(p, EP_FromJoin); + } + if( p->op==TK_FUNCTION && p->x.pList ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + unsetJoinExpr(p->x.pList->a[i].pExpr, iTable); + } + } + unsetJoinExpr(p->pLeft, iTable); + p = p->pRight; + } +} + /* ** This routine processes the join information for a SELECT statement. ** ON and USING clauses are converted into extra terms of the WHERE clause. @@ -410,11 +448,10 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; inSrc-1; i++, pRight++, pLeft++){ - Table *pLeftTab = pLeft->pTab; Table *pRightTab = pRight->pTab; int isOuter; - if( NEVER(pLeftTab==0 || pRightTab==0) ) continue; + if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; isOuter = (pRight->fg.jointype & JT_OUTER)!=0; /* When the NATURAL keyword is present, add WHERE clause terms for @@ -488,13 +525,61 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ return 0; } -/* Forward reference */ -static KeyInfo *keyInfoFromExprList( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* Form the KeyInfo object from this ExprList */ - int iStart, /* Begin with this column of pList */ - int nExtra /* Add this many extra columns to the end */ -); +/* +** An instance of this object holds information (beyond pParse and pSelect) +** needed to load the next result row that is to be added to the sorter. +*/ +typedef struct RowLoadInfo RowLoadInfo; +struct RowLoadInfo { + int regResult; /* Store results in array of registers here */ + u8 ecelFlags; /* Flag argument to ExprCodeExprList() */ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + ExprList *pExtra; /* Extra columns needed by sorter refs */ + int regExtraResult; /* Where to load the extra columns */ +#endif +}; + +/* +** This routine does the work of loading query data into an array of +** registers so that it can be added to the sorter. +*/ +static void innerLoopLoadRow( + Parse *pParse, /* Statement under construction */ + Select *pSelect, /* The query being coded */ + RowLoadInfo *pInfo /* Info needed to complete the row load */ +){ + sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult, + 0, pInfo->ecelFlags); +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( pInfo->pExtra ){ + sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0); + sqlite3ExprListDelete(pParse->db, pInfo->pExtra); + } +#endif +} + +/* +** Code the OP_MakeRecord instruction that generates the entry to be +** added into the sorter. +** +** Return the register in which the result is stored. +*/ +static int makeSorterRecord( + Parse *pParse, + SortCtx *pSort, + Select *pSelect, + int regBase, + int nBase +){ + int nOBSat = pSort->nOBSat; + Vdbe *v = pParse->pVdbe; + int regOut = ++pParse->nMem; + if( pSort->pDeferredRowLoad ){ + innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut); + return regOut; +} /* ** Generate code that will push the record in registers regData @@ -506,7 +591,7 @@ static void pushOntoSorter( Select *pSelect, /* The whole SELECT statement */ int regData, /* First register holding data to be sorted */ int regOrigData, /* First register holding data before packing */ - int nData, /* Number of elements in the data array */ + int nData, /* Number of elements in the regData data array */ int nPrefixReg /* No. of reg prior to regData available for use */ ){ Vdbe *v = pParse->pVdbe; /* Stmt under construction */ @@ -514,16 +599,32 @@ static void pushOntoSorter( int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ int regBase; /* Regs for sorter record */ - int regRecord = ++pParse->nMem; /* Assembled sorter record */ + int regRecord = 0; /* Assembled sorter record */ int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ int op; /* Opcode to add sorter record to sorter */ int iLimit; /* LIMIT counter */ + int iSkip = 0; /* End of the sorter insert loop */ assert( bSeq==0 || bSeq==1 ); + + /* Three cases: + ** (1) The data to be sorted has already been packed into a Record + ** by a prior OP_MakeRecord. In this case nData==1 and regData + ** will be completely unrelated to regOrigData. + ** (2) All output columns are included in the sort record. In that + ** case regData==regOrigData. + ** (3) Some output columns are omitted from the sort record due to + ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the + ** SQLITE_ECEL_OMITREF optimization, or due to the + ** SortCtx.pDeferredRowLoad optimiation. In any of these cases + ** regOrigData is 0 to prevent this routine from trying to copy + ** values that might not yet exist. + */ assert( nData==1 || regData==regOrigData || regOrigData==0 ); + if( nPrefixReg ){ assert( nPrefixReg==nExpr+bSeq ); - regBase = regData - nExpr - bSeq; + regBase = regData - nPrefixReg; }else{ regBase = pParse->nMem + 1; pParse->nMem += nBase; @@ -539,7 +640,6 @@ static void pushOntoSorter( if( nPrefixReg==0 && nData>0 ){ sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord); if( nOBSat>0 ){ int regPrevKey; /* The first nOBSat columns of the previous row */ int addrFirst; /* Address of the OP_IfNot opcode */ @@ -548,6 +648,7 @@ static void pushOntoSorter( int nKey; /* Number of sorting key columns, including OP_Sequence */ KeyInfo *pKI; /* Original KeyInfo on the sorter table */ + regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); regPrevKey = pParse->nMem+1; pParse->nMem += pSort->nOBSat; nKey = nExpr - pSort->nOBSat + bSeq; @@ -565,7 +666,7 @@ static void pushOntoSorter( memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */ sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); testcase( pKI->nAllField > pKI->nKeyField+2 ); - pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, + pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); @@ -581,6 +682,34 @@ static void pushOntoSorter( sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); sqlite3VdbeJumpHere(v, addrJmp); } + if( iLimit ){ + /* At this point the values for the new sorter entry are stored + ** in an array of registers. They need to be composed into a record + ** and inserted into the sorter if either (a) there are currently + ** less than LIMIT+OFFSET items or (b) the new record is smaller than + ** the largest record currently in the sorter. If (b) is true and there + ** are already LIMIT+OFFSET items in the sorter, delete the largest + ** entry before inserting the new one. This way there are never more + ** than LIMIT+OFFSET items in the sorter. + ** + ** If the new record does not need to be inserted into the sorter, + ** jump to the next iteration of the loop. If the pSort->labelOBLopt + ** value is not zero, then it is a label of where to jump. Otherwise, + ** just bypass the row insert logic. See the header comment on the + ** sqlite3WhereOrderByLimitOptLabel() function for additional info. + */ + int iCsr = pSort->iECursor; + sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0); + iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE, + iCsr, 0, regBase+nOBSat, nExpr-nOBSat); + VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_Delete, iCsr); + } + if( regRecord==0 ){ + regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); + } if( pSort->sortFlags & SORTFLAG_UseSorter ){ op = OP_SorterInsert; }else{ @@ -588,33 +717,9 @@ static void pushOntoSorter( } sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, regBase+nOBSat, nBase-nOBSat); - if( iLimit ){ - int addr; - int r1 = 0; - /* Fill the sorter until it contains LIMIT+OFFSET entries. (The iLimit - ** register is initialized with value of LIMIT+OFFSET.) After the sorter - ** fills up, delete the least entry in the sorter after each insert. - ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */ - addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v); - sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); - if( pSort->bOrderedInnerLoop ){ - r1 = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1); - VdbeComment((v, "seq")); - } - sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); - if( pSort->bOrderedInnerLoop ){ - /* If the inner loop is driven by an index such that values from - ** the same iteration of the inner loop are in sorted order, then - ** immediately jump to the next iteration of an inner loop if the - ** entry from the current iteration does not fit into the top - ** LIMIT+OFFSET entries of the sorter. */ - int iBrk = sqlite3VdbeCurrentAddr(v) + 2; - sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1); - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); - VdbeCoverage(v); - } - sqlite3VdbeJumpHere(v, addr); + if( iSkip ){ + sqlite3VdbeChangeP2(v, iSkip, + pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); } } @@ -660,20 +765,100 @@ static void codeDistinct( sqlite3ReleaseTempReg(pParse, r1); } +#ifdef SQLITE_ENABLE_SORTER_REFERENCES +/* +** This function is called as part of inner-loop generation for a SELECT +** statement with an ORDER BY that is not optimized by an index. It +** determines the expressions, if any, that the sorter-reference +** optimization should be used for. The sorter-reference optimization +** is used for SELECT queries like: +** +** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10 +** +** If the optimization is used for expression "bigblob", then instead of +** storing values read from that column in the sorter records, the PK of +** the row from table t1 is stored instead. Then, as records are extracted from +** the sorter to return to the user, the required value of bigblob is +** retrieved directly from table t1. If the values are very large, this +** can be more efficient than storing them directly in the sorter records. +** +** The ExprList_item.bSorterRef flag is set for each expression in pEList +** for which the sorter-reference optimization should be enabled. +** Additionally, the pSort->aDefer[] array is populated with entries +** for all cursors required to evaluate all selected expressions. Finally. +** output variable (*ppExtra) is set to an expression list containing +** expressions for all extra PK values that should be stored in the +** sorter records. +*/ +static void selectExprDefer( + Parse *pParse, /* Leave any error here */ + SortCtx *pSort, /* Sorter context */ + ExprList *pEList, /* Expressions destined for sorter */ + ExprList **ppExtra /* Expressions to append to sorter record */ +){ + int i; + int nDefer = 0; + ExprList *pExtra = 0; + for(i=0; inExpr; i++){ + struct ExprList_item *pItem = &pEList->a[i]; + if( pItem->u.x.iOrderByCol==0 ){ + Expr *pExpr = pItem->pExpr; + Table *pTab = pExpr->y.pTab; + if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab) + && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF) + ){ + int j; + for(j=0; jaDefer[j].iCsr==pExpr->iTable ) break; + } + if( j==nDefer ){ + if( nDefer==ArraySize(pSort->aDefer) ){ + continue; + }else{ + int nKey = 1; + int k; + Index *pPk = 0; + if( !HasRowid(pTab) ){ + pPk = sqlite3PrimaryKeyIndex(pTab); + nKey = pPk->nKeyCol; + } + for(k=0; kiTable = pExpr->iTable; + pNew->y.pTab = pExpr->y.pTab; + pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; + pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); + } + } + pSort->aDefer[nDefer].pTab = pExpr->y.pTab; + pSort->aDefer[nDefer].iCsr = pExpr->iTable; + pSort->aDefer[nDefer].nKey = nKey; + nDefer++; + } + } + pItem->bSorterRef = 1; + } + } + } + pSort->nDefer = (u8)nDefer; + *ppExtra = pExtra; +} +#endif + /* ** This routine generates the code for the inside of the inner loop ** of a SELECT. ** -** If srcTab is negative, then the pEList expressions +** If srcTab is negative, then the p->pEList expressions ** are evaluated in order to get the data for this row. If srcTab is -** zero or more, then data is pulled from srcTab and pEList is used only +** zero or more, then data is pulled from srcTab and p->pEList is used only ** to get the number of columns and the collation sequence for each column. */ static void selectInnerLoop( Parse *pParse, /* The parser context */ Select *p, /* The complete select statement being coded */ - ExprList *pEList, /* List of values being extracted */ - int srcTab, /* Pull data from this table */ + int srcTab, /* Pull data from this table if non-negative */ SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ SelectDest *pDest, /* How to dispose of the results */ @@ -687,6 +872,7 @@ static void selectInnerLoop( int iParm = pDest->iSDParm; /* First argument to disposal method */ int nResultCol; /* Number of result columns */ int nPrefixReg = 0; /* Number of extra registers before regResult */ + RowLoadInfo sRowLoadInfo; /* Info for deferred row loading */ /* Usually, regResult is the first cell in an array of memory cells ** containing the current result row. In this case regOrig is set to the @@ -697,7 +883,7 @@ static void selectInnerLoop( int regOrig; /* Start of memory holding full result (or 0) */ assert( v ); - assert( pEList!=0 ); + assert( p->pEList!=0 ); hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; if( pSort && pSort->pOrderBy==0 ) pSort = 0; if( pSort==0 && !hasDistinct ){ @@ -707,7 +893,7 @@ static void selectInnerLoop( /* Pull the requested columns. */ - nResultCol = pEList->nExpr; + nResultCol = p->pEList->nExpr; if( pDest->iSdst==0 ){ if( pSort ){ @@ -730,37 +916,92 @@ static void selectInnerLoop( if( srcTab>=0 ){ for(i=0; ia[i].zName)); + VdbeComment((v, "%s", p->pEList->a[i].zName)); } }else if( eDest!=SRT_Exists ){ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + ExprList *pExtra = 0; +#endif /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. */ - u8 ecelFlags; + u8 ecelFlags; /* "ecel" is an abbreviation of "ExprCodeExprList" */ + ExprList *pEList; if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){ ecelFlags = SQLITE_ECEL_DUP; }else{ ecelFlags = 0; } if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ - /* For each expression in pEList that is a copy of an expression in + /* For each expression in p->pEList that is a copy of an expression in ** the ORDER BY clause (pSort->pOrderBy), set the associated ** iOrderByCol value to one more than the index of the ORDER BY ** expression within the sort-key that pushOntoSorter() will generate. - ** This allows the pEList field to be omitted from the sorted record, + ** This allows the p->pEList field to be omitted from the sorted record, ** saving space and CPU cycles. */ ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF); + for(i=pSort->nOBSat; ipOrderBy->nExpr; i++){ int j; if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){ - pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; + p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; } } - regOrig = 0; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + selectExprDefer(pParse, pSort, p->pEList, &pExtra); + if( pExtra && pParse->db->mallocFailed==0 ){ + /* If there are any extra PK columns to add to the sorter records, + ** allocate extra memory cells and adjust the OpenEphemeral + ** instruction to account for the larger records. This is only + ** required if there are one or more WITHOUT ROWID tables with + ** composite primary keys in the SortCtx.aDefer[] array. */ + VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); + pOp->p2 += (pExtra->nExpr - pSort->nDefer); + pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer); + pParse->nMem += pExtra->nExpr; + } +#endif + + /* Adjust nResultCol to account for columns that are omitted + ** from the sorter by the optimizations in this branch */ + pEList = p->pEList; + for(i=0; inExpr; i++){ + if( pEList->a[i].u.x.iOrderByCol>0 +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + || pEList->a[i].bSorterRef +#endif + ){ + nResultCol--; + regOrig = 0; + } + } + + testcase( regOrig ); + testcase( eDest==SRT_Set ); + testcase( eDest==SRT_Mem ); + testcase( eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); assert( eDest==SRT_Set || eDest==SRT_Mem || eDest==SRT_Coroutine || eDest==SRT_Output ); } - nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags); + sRowLoadInfo.regResult = regResult; + sRowLoadInfo.ecelFlags = ecelFlags; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + sRowLoadInfo.pExtra = pExtra; + sRowLoadInfo.regExtraResult = regResult + nResultCol; + if( pExtra ) nResultCol += pExtra->nExpr; +#endif + if( p->iLimit + && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 + && nPrefixReg>0 + ){ + assert( pSort!=0 ); + assert( hasDistinct==0 ); + pSort->pDeferredRowLoad = &sRowLoadInfo; + regOrig = 0; + }else{ + innerLoopLoadRow(pParse, p, &sRowLoadInfo); + } } /* If the DISTINCT keyword was present on the SELECT statement @@ -792,7 +1033,7 @@ static void selectInnerLoop( iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; for(i=0; ia[i].pExpr); + CollSeq *pColl = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr); if( izAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); - sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); } @@ -950,7 +1191,6 @@ static void selectInnerLoop( sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); }else{ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); - sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); } break; } @@ -1093,7 +1333,7 @@ int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } ** function is responsible for seeing that this structure is eventually ** freed. */ -static KeyInfo *keyInfoFromExprList( +KeyInfo *sqlite3KeyInfoFromExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* Form the KeyInfo object from this ExprList */ int iStart, /* Begin with this column of pList */ @@ -1110,10 +1350,7 @@ static KeyInfo *keyInfoFromExprList( if( pInfo ){ assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=iStart, pItem=pList->a+iStart; ipExpr); - if( !pColl ) pColl = db->pDfltColl; - pInfo->aColl[i-iStart] = pColl; + pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); pInfo->aSortOrder[i-iStart] = pItem->sortOrder; } } @@ -1146,11 +1383,7 @@ static const char *selectOpName(int id){ ** is determined by the zUsage argument. */ static void explainTempTable(Parse *pParse, const char *zUsage){ - if( pParse->explain==2 ){ - Vdbe *v = pParse->pVdbe; - char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage); - sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); - } + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage)); } /* @@ -1168,42 +1401,6 @@ static void explainTempTable(Parse *pParse, const char *zUsage){ # define explainSetInteger(y,z) #endif -#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT) -/* -** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function -** is a no-op. Otherwise, it adds a single row of output to the EQP result, -** where the caption is of one of the two forms: -** -** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)" -** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)" -** -** where iSub1 and iSub2 are the integers passed as the corresponding -** function parameters, and op is the text representation of the parameter -** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT, -** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is -** false, or the second form if it is true. -*/ -static void explainComposite( - Parse *pParse, /* Parse context */ - int op, /* One of TK_UNION, TK_EXCEPT etc. */ - int iSub1, /* Subquery id 1 */ - int iSub2, /* Subquery id 2 */ - int bUseTmp /* True if a temp table was used */ -){ - assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL ); - if( pParse->explain==2 ){ - Vdbe *v = pParse->pVdbe; - char *zMsg = sqlite3MPrintf( - pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2, - bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op) - ); - sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); - } -} -#else -/* No-op versions of the explainXXX() functions and macros. */ -# define explainComposite(v,w,x,y,z) -#endif /* ** If the inner loop was generated using a non-null pOrderBy argument, @@ -1221,7 +1418,7 @@ static void generateSortTail( Vdbe *v = pParse->pVdbe; /* The prepared statement */ int addrBreak = pSort->labelDone; /* Jump here to exit loop */ int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ - int addr; + int addr; /* Top of output loop. Jump for Next. */ int addrOnce = 0; int iTab; ExprList *pOrderBy = pSort->pOrderBy; @@ -1230,11 +1427,11 @@ static void generateSortTail( int regRow; int regRowid; int iCol; - int nKey; + int nKey; /* Number of key columns in sorter record */ int iSortTab; /* Sorter cursor to read from */ - int nSortData; /* Trailing values to read from sorter */ int i; int bSeq; /* True if sorter record includes seq. no. */ + int nRefKey = 0; struct ExprList_item *aOutEx = p->pEList->a; assert( addrBreak<0 ); @@ -1243,15 +1440,24 @@ static void generateSortTail( sqlite3VdbeGoto(v, addrBreak); sqlite3VdbeResolveLabel(v, pSort->labelBkOut); } + +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + /* Open any cursors needed for sorter-reference expressions */ + for(i=0; inDefer; i++){ + Table *pTab = pSort->aDefer[i].pTab; + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); + nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey); + } +#endif + iTab = pSort->iECursor; if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ regRowid = 0; regRow = pDest->iSdst; - nSortData = nColumn; }else{ regRowid = sqlite3GetTempReg(pParse); regRow = sqlite3GetTempRange(pParse, nColumn); - nSortData = nColumn; } nKey = pOrderBy->nExpr - pSort->nOBSat; if( pSort->sortFlags & SORTFLAG_UseSorter ){ @@ -1260,7 +1466,8 @@ static void generateSortTail( if( pSort->labelBkOut ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } - sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, + nKey+1+nColumn+nRefKey); if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); VdbeCoverage(v); @@ -1273,15 +1480,59 @@ static void generateSortTail( iSortTab = iTab; bSeq = 1; } - for(i=0, iCol=nKey+bSeq; inDefer ){ + int iKey = iCol+1; + int regKey = sqlite3GetTempRange(pParse, nRefKey); + + for(i=0; inDefer; i++){ + int iCsr = pSort->aDefer[i].iCsr; + Table *pTab = pSort->aDefer[i].pTab; + int nKey = pSort->aDefer[i].nKey; + + sqlite3VdbeAddOp1(v, OP_NullRow, iCsr); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, + sqlite3VdbeCurrentAddr(v)+1, regKey); + }else{ + int k; + int iJmp; + assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey ); + for(k=0; k=0; i--){ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( aOutEx[i].bSorterRef ){ + sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); + }else +#endif + { + int iRead; + if( aOutEx[i].u.x.iOrderByCol ){ + iRead = aOutEx[i].u.x.iOrderByCol-1; + }else{ + iRead = iCol--; + } + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); + VdbeComment((v, "%s", aOutEx[i].zName?aOutEx[i].zName : aOutEx[i].zSpan)); } - sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); - VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan)); } switch( eDest ){ case SRT_Table: @@ -1296,7 +1547,6 @@ static void generateSortTail( assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, pDest->zAffSdst, nColumn); - sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); break; } @@ -1311,7 +1561,6 @@ static void generateSortTail( testcase( eDest==SRT_Coroutine ); if( eDest==SRT_Output ){ sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); - sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); }else{ sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); } @@ -1363,23 +1612,23 @@ static void generateSortTail( ** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used. */ #ifdef SQLITE_ENABLE_COLUMN_METADATA -# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F) +# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E) #else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */ -# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F) +# define columnType(A,B,C,D,E) columnTypeImpl(A,B) #endif static const char *columnTypeImpl( NameContext *pNC, +#ifndef SQLITE_ENABLE_COLUMN_METADATA + Expr *pExpr +#else Expr *pExpr, -#ifdef SQLITE_ENABLE_COLUMN_METADATA const char **pzOrigDb, const char **pzOrigTab, - const char **pzOrigCol, + const char **pzOrigCol #endif - u8 *pEstWidth ){ char const *zType = 0; int j; - u8 estWidth = 1; #ifdef SQLITE_ENABLE_COLUMN_METADATA char const *zOrigDb = 0; char const *zOrigTab = 0; @@ -1388,8 +1637,9 @@ static const char *columnTypeImpl( assert( pExpr!=0 ); assert( pNC->pSrcList!=0 ); + assert( pExpr->op!=TK_AGG_COLUMN ); /* This routine runes before aggregates + ** are processed */ switch( pExpr->op ){ - case TK_AGG_COLUMN: case TK_COLUMN: { /* The expression is a column. Locate the table the column is being ** extracted from in NameContext.pSrcList. This table may be real @@ -1398,8 +1648,6 @@ static const char *columnTypeImpl( Table *pTab = 0; /* Table structure column is extracted from */ Select *pS = 0; /* Select the column is extracted from */ int iCol = pExpr->iColumn; /* Index of column in pTab */ - testcase( pExpr->op==TK_AGG_COLUMN ); - testcase( pExpr->op==TK_COLUMN ); while( pNC && !pTab ){ SrcList *pTabList = pNC->pSrcList; for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); @@ -1432,7 +1680,7 @@ static const char *columnTypeImpl( break; } - assert( pTab && pExpr->pTab==pTab ); + assert( pTab && pExpr->y.pTab==pTab ); if( pS ){ /* The "table" is actually a sub-select or a view in the FROM clause ** of the SELECT statement. Return the declaration type and origin @@ -1448,33 +1696,32 @@ static const char *columnTypeImpl( sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); + zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol); } - }else if( pTab->pSchema ){ - /* A real table */ + }else{ + /* A real table or a CTE table */ assert( !pS ); - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iColnCol) ); #ifdef SQLITE_ENABLE_COLUMN_METADATA + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==XN_ROWID || (iCol>=0 && iColnCol) ); if( iCol<0 ){ zType = "INTEGER"; zOrigCol = "rowid"; }else{ zOrigCol = pTab->aCol[iCol].zName; zType = sqlite3ColumnType(&pTab->aCol[iCol],0); - estWidth = pTab->aCol[iCol].szEst; } zOrigTab = pTab->zName; - if( pNC->pParse ){ + if( pNC->pParse && pTab->pSchema ){ int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName; } #else + assert( iCol==XN_ROWID || (iCol>=0 && iColnCol) ); if( iCol<0 ){ zType = "INTEGER"; }else{ zType = sqlite3ColumnType(&pTab->aCol[iCol],0); - estWidth = pTab->aCol[iCol].szEst; } #endif } @@ -1493,7 +1740,7 @@ static const char *columnTypeImpl( sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth); + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); break; } #endif @@ -1507,7 +1754,6 @@ static const char *columnTypeImpl( *pzOrigCol = zOrigCol; } #endif - if( pEstWidth ) *pEstWidth = estWidth; return zType; } @@ -1534,7 +1780,7 @@ static void generateColumnTypes( const char *zOrigDb = 0; const char *zOrigTab = 0; const char *zOrigCol = 0; - zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0); + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); /* The vdbe must make its own copy of the column-type and other ** column specific strings, in case the schema is reset before this @@ -1544,7 +1790,7 @@ static void generateColumnTypes( sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); #else - zType = columnType(&sNC, p, 0, 0, 0, 0); + zType = columnType(&sNC, p, 0, 0, 0); #endif sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); } @@ -1574,9 +1820,9 @@ static void generateColumnTypes( ** other words, the zSpan of the result expression. ** ** short=ON, full=OFF: (This is the default setting). If the result -** refers directly to a table column, then the result -** column name is just the table column name: COLUMN. -** Otherwise use zSpan. +** refers directly to a table column, then the +** result column name is just the table column +** name: COLUMN. Otherwise use zSpan. ** ** full=ON, short=ANY: If the result refers directly to a table column, ** then the result column name with the table name @@ -1602,9 +1848,10 @@ static void generateColumnNames( } #endif - if( pParse->colNamesSet || db->mallocFailed ) return; + if( pParse->colNamesSet ) return; /* Column names are determined by the left-most term of a compound select */ while( pSelect->pPrior ) pSelect = pSelect->pPrior; + SELECTTRACE(1,pParse,pSelect,("generating column names\n")); pTabList = pSelect->pSrc; pEList = pSelect->pEList; assert( v!=0 ); @@ -1617,6 +1864,8 @@ static void generateColumnNames( Expr *p = pEList->a[i].pExpr; assert( p!=0 ); + assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ + assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */ if( pEList->a[i].zName ){ /* An AS clause always takes first priority */ char *zName = pEList->a[i].zName; @@ -1624,7 +1873,7 @@ static void generateColumnNames( }else if( srcName && p->op==TK_COLUMN ){ char *zCol; int iCol = p->iColumn; - pTab = p->pTab; + pTab = p->y.pTab; assert( pTab!=0 ); if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); @@ -1691,6 +1940,7 @@ int sqlite3ColumnsFromExprList( nCol = pEList->nExpr; aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); testcase( aCol==0 ); + if( nCol>32767 ) nCol = 32767; }else{ nCol = 0; aCol = 0; @@ -1710,10 +1960,12 @@ int sqlite3ColumnsFromExprList( pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } - if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){ + assert( pColExpr->op!=TK_AGG_COLUMN ); + if( pColExpr->op==TK_COLUMN ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; - Table *pTab = pColExpr->pTab; + Table *pTab = pColExpr->y.pTab; + assert( pTab!=0 ); if( iCol<0 ) iCol = pTab->iPKey; zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; }else if( pColExpr->op==TK_ID ){ @@ -1785,7 +2037,6 @@ void sqlite3SelectAddColumnTypeAndCollation( int i; Expr *p; struct ExprList_item *a; - u64 szAll = 0; assert( pSelect!=0 ); assert( (pSelect->selFlags & SF_Resolved)!=0 ); @@ -1798,10 +2049,11 @@ void sqlite3SelectAddColumnTypeAndCollation( const char *zType; int n, m; p = a[i].pExpr; - zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst); - szAll += pCol->szEst; + zType = columnType(&sNC, p, 0, 0, 0); + /* pCol->szEst = ... // Column size est for SELECT tables never used */ pCol->affinity = sqlite3ExprAffinity(p); - if( zType && (m = sqlite3Strlen30(zType))>0 ){ + if( zType ){ + m = sqlite3Strlen30(zType); n = sqlite3Strlen30(pCol->zName); pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); if( pCol->zName ){ @@ -1815,7 +2067,7 @@ void sqlite3SelectAddColumnTypeAndCollation( pCol->zColl = sqlite3DbStrDup(db, pColl->zName); } } - pTab->szTabRow = sqlite3LogEst(szAll*4); + pTab->szTabRow = 1; /* Any non-zero value works */ } /* @@ -1858,25 +2110,22 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ ** Get a VDBE for the given parser context. Create a new one if necessary. ** If an error occurs, return NULL and leave a message in pParse. */ -static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){ - Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse); - if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1); +Vdbe *sqlite3GetVdbe(Parse *pParse){ + if( pParse->pVdbe ){ + return pParse->pVdbe; + } if( pParse->pToplevel==0 && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) ){ pParse->okConstFactor = 1; } - return v; -} -Vdbe *sqlite3GetVdbe(Parse *pParse){ - Vdbe *v = pParse->pVdbe; - return v ? v : allocVdbe(pParse); + return sqlite3VdbeCreate(pParse); } /* ** Compute the iLimit and iOffset fields of the SELECT based on the -** pLimit and pOffset expressions. pLimit and pOffset hold the expressions +** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions ** that appear in the original SQL statement after the LIMIT and OFFSET ** keywords. Or NULL if those keywords are omitted. iLimit and iOffset ** are the integer memory register numbers for counters used to compute @@ -1884,15 +2133,15 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ ** iLimit and iOffset are negative. ** ** This routine changes the values of iLimit and iOffset only if -** a limit or offset is defined by pLimit and pOffset. iLimit and -** iOffset should have been preset to appropriate default values (zero) +** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit +** and iOffset should have been preset to appropriate default values (zero) ** prior to calling this routine. ** ** The iOffset register (if it exists) is initialized to the value ** of the OFFSET. The iLimit register is initialized to LIMIT. Register ** iOffset+1 is initialized to LIMIT+OFFSET. ** -** Only if pLimit!=0 or pOffset!=0 do the limit registers get +** Only if pLimit->pLeft!=0 do the limit registers get ** redefined. The UNION ALL operator uses this property to force ** the reuse of the same limit and offset registers across multiple ** SELECT statements. @@ -1902,6 +2151,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ int iLimit = 0; int iOffset; int n; + Expr *pLimit = p->pLimit; + if( p->iLimit ) return; /* @@ -1910,13 +2161,13 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ - sqlite3ExprCacheClear(pParse); - assert( p->pOffset==0 || p->pLimit!=0 ); - if( p->pLimit ){ + if( pLimit ){ + assert( pLimit->op==TK_LIMIT ); + assert( pLimit->pLeft!=0 ); p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); - if( sqlite3ExprIsInteger(p->pLimit, &n) ){ + if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ @@ -1926,15 +2177,15 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ p->selFlags |= SF_FixedLimit; } }else{ - sqlite3ExprCode(pParse, p->pLimit, iLimit); + sqlite3ExprCode(pParse, pLimit->pLeft, iLimit); sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); } - if( p->pOffset ){ + if( pLimit->pRight ){ p->iOffset = iOffset = ++pParse->nMem; pParse->nMem++; /* Allocate an extra register for limit+offset */ - sqlite3ExprCode(pParse, p->pOffset, iOffset); + sqlite3ExprCode(pParse, pLimit->pRight, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); VdbeComment((v, "OFFSET counter")); sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); @@ -2064,9 +2315,16 @@ static void generateWithRecursiveQuery( int i; /* Loop counter */ int rc; /* Result code */ ExprList *pOrderBy; /* The ORDER BY clause */ - Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ + Expr *pLimit; /* Saved LIMIT and OFFSET */ int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries"); + return; + } +#endif + /* Obtain authorization to do a recursive query */ if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; @@ -2075,10 +2333,9 @@ static void generateWithRecursiveQuery( p->nSelectRow = 320; /* 4 billion rows */ computeLimitRegisters(pParse, p, addrBreak); pLimit = p->pLimit; - pOffset = p->pOffset; regLimit = p->iLimit; regOffset = p->iOffset; - p->pLimit = p->pOffset = 0; + p->pLimit = 0; p->iLimit = p->iOffset = 0; pOrderBy = p->pOrderBy; @@ -2124,6 +2381,7 @@ static void generateWithRecursiveQuery( /* Store the results of the setup-query in Queue. */ pSetup->pNext = 0; + ExplainQueryPlan((pParse, 1, "SETUP")); rc = sqlite3Select(pParse, pSetup, &destQueue); pSetup->pNext = p; if( rc ) goto end_of_recursive_query; @@ -2143,7 +2401,7 @@ static void generateWithRecursiveQuery( /* Output the single row in Current */ addrCont = sqlite3VdbeMakeLabel(v); codeOffset(v, regOffset, addrCont); - selectInnerLoop(pParse, p, p->pEList, iCurrent, + selectInnerLoop(pParse, p, iCurrent, 0, 0, pDest, addrCont, addrBreak); if( regLimit ){ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); @@ -2158,6 +2416,7 @@ static void generateWithRecursiveQuery( sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); }else{ p->pPrior = 0; + ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); sqlite3Select(pParse, p, &destQueue); assert( p->pPrior==0 ); p->pPrior = pSetup; @@ -2171,7 +2430,6 @@ end_of_recursive_query: sqlite3ExprListDelete(pParse->db, p->pOrderBy); p->pOrderBy = pOrderBy; p->pLimit = pLimit; - p->pOffset = pOffset; return; } #endif /* SQLITE_OMIT_CTE */ @@ -2190,36 +2448,38 @@ static int multiSelectOrderBy( ** on a VALUES clause. ** ** Because the Select object originates from a VALUES clause: -** (1) It has no LIMIT or OFFSET +** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1 ** (2) All terms are UNION ALL ** (3) There is no ORDER BY clause +** +** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES +** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). +** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. +** Since the limit is exactly 1, we only need to evalutes the left-most VALUES. */ static int multiSelectValues( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ ){ - Select *pPrior; int nRow = 1; int rc = 0; + int bShowAll = p->pLimit==0; assert( p->selFlags & SF_MultiValue ); do{ assert( p->selFlags & SF_Values ); assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); - assert( p->pLimit==0 ); - assert( p->pOffset==0 ); assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); if( p->pPrior==0 ) break; assert( p->pPrior->pNext==p ); p = p->pPrior; - nRow++; + nRow += bShowAll; }while(1); + ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow, + nRow==1 ? "" : "S")); while( p ){ - pPrior = p->pPrior; - p->pPrior = 0; - rc = sqlite3Select(pParse, p, pDest); - p->pPrior = pPrior; - if( rc ) break; + selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1); + if( !bShowAll ) break; p->nSelectRow = nRow; p = p->pNext; } @@ -2268,10 +2528,6 @@ static int multiSelect( SelectDest dest; /* Alternative data destination */ Select *pDelete = 0; /* Chain of simple selects to delete */ sqlite3 *db; /* Database connection */ -#ifndef SQLITE_OMIT_EXPLAIN - int iSub1 = 0; /* EQP id of left-hand query */ - int iSub2 = 0; /* EQP id of right-hand query */ -#endif /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. @@ -2281,15 +2537,9 @@ static int multiSelect( db = pParse->db; pPrior = p->pPrior; dest = *pDest; - if( pPrior->pOrderBy ){ - sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", - selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } - if( pPrior->pLimit ){ - sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", - selectOpName(p->op)); + if( pPrior->pOrderBy || pPrior->pLimit ){ + sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", + pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op)); rc = 1; goto multi_select_end; } @@ -2328,226 +2578,231 @@ static int multiSelect( */ if( p->pOrderBy ){ return multiSelectOrderBy(pParse, p, pDest); - }else + }else{ - /* Generate code for the left and right SELECT statements. - */ - switch( p->op ){ - case TK_ALL: { - int addr = 0; - int nLimit; - assert( !pPrior->pLimit ); - pPrior->iLimit = p->iLimit; - pPrior->iOffset = p->iOffset; - pPrior->pLimit = p->pLimit; - pPrior->pOffset = p->pOffset; - explainSetInteger(iSub1, pParse->iNextSelectId); - rc = sqlite3Select(pParse, pPrior, &dest); - p->pLimit = 0; - p->pOffset = 0; - if( rc ){ - goto multi_select_end; - } - p->pPrior = 0; - p->iLimit = pPrior->iLimit; - p->iOffset = pPrior->iOffset; - if( p->iLimit ){ - addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); - VdbeComment((v, "Jump ahead if LIMIT reached")); - if( p->iOffset ){ - sqlite3VdbeAddOp3(v, OP_OffsetLimit, - p->iLimit, p->iOffset+1, p->iOffset); - } - } - explainSetInteger(iSub2, pParse->iNextSelectId); - rc = sqlite3Select(pParse, p, &dest); - testcase( rc!=SQLITE_OK ); - pDelete = p->pPrior; - p->pPrior = pPrior; - p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - if( pPrior->pLimit - && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) - && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) - ){ - p->nSelectRow = sqlite3LogEst((u64)nLimit); - } - if( addr ){ - sqlite3VdbeJumpHere(v, addr); - } - break; +#ifndef SQLITE_OMIT_EXPLAIN + if( pPrior->pPrior==0 ){ + ExplainQueryPlan((pParse, 1, "COMPOUND QUERY")); + ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY")); } - case TK_EXCEPT: - case TK_UNION: { - int unionTab; /* Cursor number of the temporary table holding result */ - u8 op = 0; /* One of the SRT_ operations to apply to self */ - int priorOp; /* The SRT_ operation to apply to prior selects */ - Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ - int addr; - SelectDest uniondest; +#endif - testcase( p->op==TK_EXCEPT ); - testcase( p->op==TK_UNION ); - priorOp = SRT_Union; - if( dest.eDest==priorOp ){ - /* We can reuse a temporary table generated by a SELECT to our - ** right. + /* Generate code for the left and right SELECT statements. + */ + switch( p->op ){ + case TK_ALL: { + int addr = 0; + int nLimit; + assert( !pPrior->pLimit ); + pPrior->iLimit = p->iLimit; + pPrior->iOffset = p->iOffset; + pPrior->pLimit = p->pLimit; + rc = sqlite3Select(pParse, pPrior, &dest); + p->pLimit = 0; + if( rc ){ + goto multi_select_end; + } + p->pPrior = 0; + p->iLimit = pPrior->iLimit; + p->iOffset = pPrior->iOffset; + if( p->iLimit ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); + VdbeComment((v, "Jump ahead if LIMIT reached")); + if( p->iOffset ){ + sqlite3VdbeAddOp3(v, OP_OffsetLimit, + p->iLimit, p->iOffset+1, p->iOffset); + } + } + ExplainQueryPlan((pParse, 1, "UNION ALL")); + rc = sqlite3Select(pParse, p, &dest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + if( pPrior->pLimit + && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit) + && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) + ){ + p->nSelectRow = sqlite3LogEst((u64)nLimit); + } + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + } + break; + } + case TK_EXCEPT: + case TK_UNION: { + int unionTab; /* Cursor number of the temp table holding result */ + u8 op = 0; /* One of the SRT_ operations to apply to self */ + int priorOp; /* The SRT_ operation to apply to prior selects */ + Expr *pLimit; /* Saved values of p->nLimit */ + int addr; + SelectDest uniondest; + + testcase( p->op==TK_EXCEPT ); + testcase( p->op==TK_UNION ); + priorOp = SRT_Union; + if( dest.eDest==priorOp ){ + /* We can reuse a temporary table generated by a SELECT to our + ** right. + */ + assert( p->pLimit==0 ); /* Not allowed on leftward elements */ + unionTab = dest.iSDParm; + }else{ + /* We will need to create our own temporary table to hold the + ** intermediate results. + */ + unionTab = pParse->nTab++; + assert( p->pOrderBy==0 ); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + findRightmost(p)->selFlags |= SF_UsesEphemeral; + assert( p->pEList ); + } + + /* Code the SELECT statements to our left */ - assert( p->pLimit==0 ); /* Not allowed on leftward elements */ - assert( p->pOffset==0 ); /* Not allowed on leftward elements */ - unionTab = dest.iSDParm; - }else{ - /* We will need to create our own temporary table to hold the - ** intermediate results. + assert( !pPrior->pOrderBy ); + sqlite3SelectDestInit(&uniondest, priorOp, unionTab); + rc = sqlite3Select(pParse, pPrior, &uniondest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT statement */ - unionTab = pParse->nTab++; + if( p->op==TK_EXCEPT ){ + op = SRT_Except; + }else{ + assert( p->op==TK_UNION ); + op = SRT_Union; + } + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + uniondest.eDest = op; + ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", + selectOpName(p->op))); + rc = sqlite3Select(pParse, p, &uniondest); + testcase( rc!=SQLITE_OK ); + /* Query flattening in sqlite3Select() might refill p->pOrderBy. + ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ + sqlite3ExprListDelete(db, p->pOrderBy); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->pOrderBy = 0; + if( p->op==TK_UNION ){ + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + p->iLimit = 0; + p->iOffset = 0; + + /* Convert the data in the temporary table into whatever form + ** it is that we currently need. + */ + assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); + if( dest.eDest!=priorOp ){ + int iCont, iBreak, iStart; + assert( p->pEList ); + iBreak = sqlite3VdbeMakeLabel(v); + iCont = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); + iStart = sqlite3VdbeCurrentAddr(v); + selectInnerLoop(pParse, p, unionTab, + 0, 0, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); + } + break; + } + default: assert( p->op==TK_INTERSECT ); { + int tab1, tab2; + int iCont, iBreak, iStart; + Expr *pLimit; + int addr; + SelectDest intersectdest; + int r1; + + /* INTERSECT is different from the others since it requires + ** two temporary tables. Hence it has its own case. Begin + ** by allocating the tables we will need. + */ + tab1 = pParse->nTab++; + tab2 = pParse->nTab++; assert( p->pOrderBy==0 ); - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); + + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); assert( p->addrOpenEphm[0] == -1 ); p->addrOpenEphm[0] = addr; findRightmost(p)->selFlags |= SF_UsesEphemeral; assert( p->pEList ); - } - - /* Code the SELECT statements to our left - */ - assert( !pPrior->pOrderBy ); - sqlite3SelectDestInit(&uniondest, priorOp, unionTab); - explainSetInteger(iSub1, pParse->iNextSelectId); - rc = sqlite3Select(pParse, pPrior, &uniondest); - if( rc ){ - goto multi_select_end; - } - - /* Code the current SELECT statement - */ - if( p->op==TK_EXCEPT ){ - op = SRT_Except; - }else{ - assert( p->op==TK_UNION ); - op = SRT_Union; - } - p->pPrior = 0; - pLimit = p->pLimit; - p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; - uniondest.eDest = op; - explainSetInteger(iSub2, pParse->iNextSelectId); - rc = sqlite3Select(pParse, p, &uniondest); - testcase( rc!=SQLITE_OK ); - /* Query flattening in sqlite3Select() might refill p->pOrderBy. - ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ - sqlite3ExprListDelete(db, p->pOrderBy); - pDelete = p->pPrior; - p->pPrior = pPrior; - p->pOrderBy = 0; - if( p->op==TK_UNION ){ - p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - } - sqlite3ExprDelete(db, p->pLimit); - p->pLimit = pLimit; - p->pOffset = pOffset; - p->iLimit = 0; - p->iOffset = 0; - - /* Convert the data in the temporary table into whatever form - ** it is that we currently need. - */ - assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); - if( dest.eDest!=priorOp ){ - int iCont, iBreak, iStart; + + /* Code the SELECTs to our left into temporary table "tab1". + */ + sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); + rc = sqlite3Select(pParse, pPrior, &intersectdest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT into temporary table "tab2" + */ + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); + assert( p->addrOpenEphm[1] == -1 ); + p->addrOpenEphm[1] = addr; + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + intersectdest.iSDParm = tab2; + ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", + selectOpName(p->op))); + rc = sqlite3Select(pParse, p, &intersectdest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + if( p->nSelectRow>pPrior->nSelectRow ){ + p->nSelectRow = pPrior->nSelectRow; + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + + /* Generate code to take the intersection of the two temporary + ** tables. + */ assert( p->pEList ); iBreak = sqlite3VdbeMakeLabel(v); iCont = sqlite3VdbeMakeLabel(v); computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); - iStart = sqlite3VdbeCurrentAddr(v); - selectInnerLoop(pParse, p, p->pEList, unionTab, + sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); + r1 = sqlite3GetTempReg(pParse); + iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); + sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, r1); + selectInnerLoop(pParse, p, tab1, 0, 0, &dest, iCont, iBreak); sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); + sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); + sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); + break; } - break; } - default: assert( p->op==TK_INTERSECT ); { - int tab1, tab2; - int iCont, iBreak, iStart; - Expr *pLimit, *pOffset; - int addr; - SelectDest intersectdest; - int r1; - - /* INTERSECT is different from the others since it requires - ** two temporary tables. Hence it has its own case. Begin - ** by allocating the tables we will need. - */ - tab1 = pParse->nTab++; - tab2 = pParse->nTab++; - assert( p->pOrderBy==0 ); - - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); - assert( p->addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - findRightmost(p)->selFlags |= SF_UsesEphemeral; - assert( p->pEList ); - - /* Code the SELECTs to our left into temporary table "tab1". - */ - sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); - explainSetInteger(iSub1, pParse->iNextSelectId); - rc = sqlite3Select(pParse, pPrior, &intersectdest); - if( rc ){ - goto multi_select_end; - } - - /* Code the current SELECT into temporary table "tab2" - */ - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); - assert( p->addrOpenEphm[1] == -1 ); - p->addrOpenEphm[1] = addr; - p->pPrior = 0; - pLimit = p->pLimit; - p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; - intersectdest.iSDParm = tab2; - explainSetInteger(iSub2, pParse->iNextSelectId); - rc = sqlite3Select(pParse, p, &intersectdest); - testcase( rc!=SQLITE_OK ); - pDelete = p->pPrior; - p->pPrior = pPrior; - if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; - sqlite3ExprDelete(db, p->pLimit); - p->pLimit = pLimit; - p->pOffset = pOffset; - - /* Generate code to take the intersection of the two temporary - ** tables. - */ - assert( p->pEList ); - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); - r1 = sqlite3GetTempReg(pParse); - iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); - sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, r1); - selectInnerLoop(pParse, p, p->pEList, tab1, - 0, 0, &dest, iCont, iBreak); - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); - sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); - break; + + #ifndef SQLITE_OMIT_EXPLAIN + if( p->pNext==0 ){ + ExplainQueryPlanPop(pParse); } + #endif } - - explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL); - + /* Compute collating sequences used by ** temporary tables needed to implement the compound select. ** Attach the KeyInfo structure to all temporary tables. @@ -2698,7 +2953,6 @@ static int generateOutputSubroutine( r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); - sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); sqlite3ReleaseTempReg(pParse, r1); @@ -2741,7 +2995,6 @@ static int generateOutputSubroutine( default: { assert( pDest->eDest==SRT_Output ); sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); - sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); break; } } @@ -2885,10 +3138,6 @@ static int multiSelectOrderBy( ExprList *pOrderBy; /* The ORDER BY clause */ int nOrderBy; /* Number of terms in the ORDER BY clause */ int *aPermute; /* Mapping from ORDER BY terms to result set columns */ -#ifndef SQLITE_OMIT_EXPLAIN - int iSub1; /* EQP id of left-hand query */ - int iSub2; /* EQP id of right-hand query */ -#endif assert( p->pOrderBy!=0 ); assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ @@ -3000,8 +3249,6 @@ static int multiSelectOrderBy( } sqlite3ExprDelete(db, p->pLimit); p->pLimit = 0; - sqlite3ExprDelete(db, p->pOffset); - p->pOffset = 0; regAddrA = ++pParse->nMem; regAddrB = ++pParse->nMem; @@ -3010,6 +3257,8 @@ static int multiSelectOrderBy( sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); + ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op))); + /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. */ @@ -3017,7 +3266,7 @@ static int multiSelectOrderBy( addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); VdbeComment((v, "left SELECT")); pPrior->iLimit = regLimitA; - explainSetInteger(iSub1, pParse->iNextSelectId); + ExplainQueryPlan((pParse, 1, "LEFT")); sqlite3Select(pParse, pPrior, &destA); sqlite3VdbeEndCoroutine(v, regAddrA); sqlite3VdbeJumpHere(v, addr1); @@ -3032,7 +3281,7 @@ static int multiSelectOrderBy( savedOffset = p->iOffset; p->iLimit = regLimitB; p->iOffset = 0; - explainSetInteger(iSub2, pParse->iNextSelectId); + ExplainQueryPlan((pParse, 1, "RIGHT")); sqlite3Select(pParse, p, &destB); p->iLimit = savedLimit; p->iOffset = savedOffset; @@ -3144,7 +3393,7 @@ static int multiSelectOrderBy( /*** TBD: Insert subroutine calls to close cursors on incomplete **** subqueries ****/ - explainComposite(pParse, p->op, iSub1, iSub2, 0); + ExplainQueryPlanPop(pParse); return pParse->nErr!=0; } #endif @@ -3187,7 +3436,9 @@ static Expr *substExpr( Expr *pExpr /* Expr in which substitution occurs */ ){ if( pExpr==0 ) return 0; - if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){ + if( ExprHasProperty(pExpr, EP_FromJoin) + && pExpr->iRightJoinTable==pSubst->iTable + ){ pExpr->iRightJoinTable = pSubst->iNewTable; } if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){ @@ -3198,7 +3449,7 @@ static Expr *substExpr( Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; Expr ifNullRow; assert( pSubst->pEList!=0 && pExpr->iColumnpEList->nExpr ); - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + assert( pExpr->pRight==0 ); if( sqlite3ExprIsVector(pCopy) ){ sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ @@ -3300,68 +3551,74 @@ static void substSelect( ** exist on the table t1, a complete scan of the data might be ** avoided. ** -** Flattening is only attempted if all of the following are true: +** Flattening is subject to the following constraints: ** -** (1) The subquery and the outer query do not both use aggregates. +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** The subquery and the outer query cannot both be aggregates. ** -** (2) The subquery is not an aggregate or (2a) the outer query is not a join -** and (2b) the outer query does not use subqueries other than the one -** FROM-clause subquery that is a candidate for flattening. (2b is -** due to ticket [2f7170d73bf9abf80] from 2015-02-09.) +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** (2) If the subquery is an aggregate then +** (2a) the outer query must not be a join and +** (2b) the outer query must not use subqueries +** other than the one FROM-clause subquery that is a candidate +** for flattening. (This is due to ticket [2f7170d73bf9abf80] +** from 2015-02-09.) ** -** (3) The subquery is not the right operand of a LEFT JOIN -** or (a) the subquery is not itself a join and (b) the FROM clause -** of the subquery does not contain a virtual table and (c) the -** outer query is not an aggregate. +** (3) If the subquery is the right operand of a LEFT JOIN then +** (3a) the subquery may not be a join and +** (3b) the FROM clause of the subquery may not contain a virtual +** table and +** (3c) the outer query may not be an aggregate. ** -** (4) The subquery is not DISTINCT. +** (4) The subquery can not be DISTINCT. ** ** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT ** sub-queries that were excluded from this optimization. Restriction ** (4) has since been expanded to exclude all DISTINCT subqueries. ** -** (6) The subquery does not use aggregates or the outer query is not -** DISTINCT. +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** If the subquery is aggregate, the outer query may not be DISTINCT. ** -** (7) The subquery has a FROM clause. TODO: For subqueries without +** (7) The subquery must have a FROM clause. TODO: For subqueries without ** A FROM clause, consider adding a FROM clause with the special ** table sqlite_once that consists of a single row containing a ** single NULL. ** -** (8) The subquery does not use LIMIT or the outer query is not a join. +** (8) If the subquery uses LIMIT then the outer query may not be a join. ** -** (9) The subquery does not use LIMIT or the outer query does not use -** aggregates. +** (9) If the subquery uses LIMIT then the outer query may not be aggregate. ** ** (**) Restriction (10) was removed from the code on 2005-02-05 but we ** accidently carried the comment forward until 2014-09-15. Original -** text: "The subquery does not use aggregates or the outer query -** does not use LIMIT." +** constraint: "If the subquery is aggregate then the outer query +** may not use LIMIT." ** -** (11) The subquery and the outer query do not both have ORDER BY clauses. +** (11) The subquery and the outer query may not both have ORDER BY clauses. ** ** (**) Not implemented. Subsumed into restriction (3). Was previously ** a separate restriction deriving from ticket #350. ** -** (13) The subquery and outer query do not both use LIMIT. +** (13) The subquery and outer query may not both use LIMIT. ** -** (14) The subquery does not use OFFSET. +** (14) The subquery may not use OFFSET. ** -** (15) The outer query is not part of a compound select or the -** subquery does not have a LIMIT clause. +** (15) If the outer query is part of a compound select, then the +** subquery may not use LIMIT. ** (See ticket #2339 and ticket [02a8e81d44]). ** -** (16) The outer query is not an aggregate or the subquery does -** not contain ORDER BY. (Ticket #2942) This used to not matter +** (16) If the outer query is aggregate, then the subquery may not +** use ORDER BY. (Ticket #2942) This used to not matter ** until we introduced the group_concat() function. ** -** (17) The sub-query is not a compound select, or it is a UNION ALL -** compound clause made up entirely of non-aggregate queries, and -** the parent query: -** -** * is not itself part of a compound select, -** * is not an aggregate or DISTINCT query, and -** * is not a join +** (17) If the subquery is a compound select, then +** (17a) all compound operators must be a UNION ALL, and +** (17b) no terms within the subquery compound may be aggregate +** or DISTINCT, and +** (17c) every term within the subquery compound must have a FROM clause +** (17d) the outer query may not be +** (17d1) aggregate, or +** (17d2) DISTINCT, or +** (17d3) a join. ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, @@ -3377,10 +3634,10 @@ static void substSelect( ** syntax error and return a detailed message. ** ** (18) If the sub-query is a compound select, then all terms of the -** ORDER by clause of the parent must be simple references to +** ORDER BY clause of the parent must be simple references to ** columns of the sub-query. ** -** (19) The subquery does not use LIMIT or the outer query does not +** (19) If the subquery uses LIMIT then the outer query may not ** have a WHERE clause. ** ** (20) If the sub-query is a compound select, then it must not use @@ -3389,25 +3646,31 @@ static void substSelect( ** appear as unmodified result columns in the outer query. But we ** have other optimizations in mind to deal with that case. ** -** (21) The subquery does not use LIMIT or the outer query is not +** (21) If the subquery uses LIMIT then the outer query may not be ** DISTINCT. (See ticket [752e1646fc]). ** -** (22) The subquery is not a recursive CTE. +** (22) The subquery may not be a recursive CTE. ** -** (23) The parent is not a recursive CTE, or the sub-query is not a -** compound query. This restriction is because transforming the +** (**) Subsumed into restriction (17d3). Was: If the outer query is +** a recursive CTE, then the sub-query may not be a compound query. +** This restriction is because transforming the ** parent to a compound query confuses the code that handles ** recursive queries in multiSelect(). ** -** (24) The subquery is not an aggregate that uses the built-in min() or +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** The subquery may not be an aggregate that uses the built-in min() or ** or max() functions. (Without this restriction, a query like: ** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily ** return the value X for which Y was maximal.) ** +** (25) If either the subquery or the parent query contains a window +** function in the select list or ORDER BY clause, flattening +** is not attempted. +** ** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query -** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. +** uses aggregates. ** ** If flattening is not attempted, this routine is a no-op and returns 0. ** If flattening is attempted this routine returns 1. @@ -3419,8 +3682,7 @@ static int flattenSubquery( Parse *pParse, /* Parsing context */ Select *p, /* The parent or outer SELECT statement */ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ - int isAgg, /* True if outer SELECT uses aggregate functions */ - int subqueryIsAgg /* True if the subquery uses aggregate functions */ + int isAgg /* True if outer SELECT uses aggregate functions */ ){ const char *zSavedAuthContext = pParse->zAuthContext; Select *pParent; /* Current UNION ALL term of the other query */ @@ -3439,7 +3701,7 @@ static int flattenSubquery( /* Check to see if flattening is permitted. Return 0 if not. */ assert( p!=0 ); - assert( p->pPrior==0 ); /* Unable to flatten compound queries */ + assert( p->pPrior==0 ); if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; pSrc = p->pSrc; assert( pSrc && iFrom>=0 && iFromnSrc ); @@ -3447,16 +3709,10 @@ static int flattenSubquery( iParent = pSubitem->iCursor; pSub = pSubitem->pSelect; assert( pSub!=0 ); - if( subqueryIsAgg ){ - if( isAgg ) return 0; /* Restriction (1) */ - if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */ - if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery)) - || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0 - || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0 - ){ - return 0; /* Restriction (2b) */ - } - } + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */ +#endif pSubSrc = pSub->pSrc; assert( pSubSrc ); @@ -3466,18 +3722,15 @@ static int flattenSubquery( ** became arbitrary expressions, we were forced to add restrictions (13) ** and (14). */ if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ - if( pSub->pOffset ) return 0; /* Restriction (14) */ + if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */ if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ return 0; /* Restriction (15) */ } if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ - if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */ + if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (4) */ if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ return 0; /* Restrictions (8)(9) */ } - if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){ - return 0; /* Restriction (6) */ - } if( p->pOrderBy && pSub->pOrderBy ){ return 0; /* Restriction (11) */ } @@ -3486,18 +3739,14 @@ static int flattenSubquery( if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ return 0; /* Restriction (21) */ } - testcase( pSub->selFlags & SF_Recursive ); - testcase( pSub->selFlags & SF_MinMaxAgg ); - if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){ - return 0; /* Restrictions (22) and (24) */ - } - if( (p->selFlags & SF_Recursive) && pSub->pPrior ){ - return 0; /* Restriction (23) */ + if( pSub->selFlags & (SF_Recursive) ){ + return 0; /* Restrictions (22) */ } /* ** If the subquery is the right operand of a LEFT JOIN, then the - ** subquery may not be a join itself. Example of why this is not allowed: + ** subquery may not be a join itself (3a). Example of why this is not + ** allowed: ** ** t1 LEFT OUTER JOIN (t2 JOIN t3) ** @@ -3508,54 +3757,56 @@ static int flattenSubquery( ** which is not at all the same thing. ** ** If the subquery is the right operand of a LEFT JOIN, then the outer - ** query cannot be an aggregate. This is an artifact of the way aggregates - ** are processed - there is no mechanism to determine if the LEFT JOIN - ** table should be all-NULL. + ** query cannot be an aggregate. (3c) This is an artifact of the way + ** aggregates are processed - there is no mechanism to determine if + ** the LEFT JOIN table should be all-NULL. ** ** See also tickets #306, #350, and #3300. */ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ isLeftJoin = 1; if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){ - return 0; /* Restriction (3) */ + /* (3a) (3c) (3b) */ + return 0; } } #ifdef SQLITE_EXTRA_IFNULLROW else if( iFrom>0 && !isAgg ){ /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for - ** every reference to any result column from subquery in a join, even though - ** they are not necessary. This will stress-test the OP_IfNullRow opcode. */ + ** every reference to any result column from subquery in a join, even + ** though they are not necessary. This will stress-test the OP_IfNullRow + ** opcode. */ isLeftJoin = -1; } #endif - /* Restriction 17: If the sub-query is a compound SELECT, then it must + /* Restriction (17): If the sub-query is a compound SELECT, then it must ** use only the UNION ALL operator. And none of the simple select queries ** that make up the compound SELECT are allowed to be aggregate or distinct ** queries. */ if( pSub->pPrior ){ if( pSub->pOrderBy ){ - return 0; /* Restriction 20 */ + return 0; /* Restriction (20) */ } if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ - return 0; + return 0; /* (17d1), (17d2), or (17d3) */ } for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); assert( pSub->pSrc!=0 ); assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); - if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 - || (pSub1->pPrior && pSub1->op!=TK_ALL) - || pSub1->pSrc->nSrc<1 + if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ + || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ + || pSub1->pSrc->nSrc<1 /* (17c) */ ){ return 0; } testcase( pSub1->pSrc->nSrc>1 ); } - /* Restriction 18. */ + /* Restriction (18). */ if( p->pOrderBy ){ int ii; for(ii=0; iipOrderBy->nExpr; ii++){ @@ -3564,9 +3815,17 @@ static int flattenSubquery( } } + /* Ex-restriction (23): + ** The only way that the recursive part of a CTE can contain a compound + ** subquery is for the subquery to be one term of a join. But if the + ** subquery is a join, then the flattening has already been stopped by + ** restriction (17d3) + */ + assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 ); + /***** If we reach this point, flattening is permitted. *****/ - SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n", - pSub->zSelName, pSub, iFrom)); + SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", + pSub->selId, pSub, iFrom)); /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; @@ -3611,16 +3870,12 @@ static int flattenSubquery( Select *pNew; ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; - Expr *pOffset = p->pOffset; Select *pPrior = p->pPrior; p->pOrderBy = 0; p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; - p->pOffset = 0; pNew = sqlite3SelectDup(db, p, 0); - sqlite3SelectSetName(pNew, pSub->zSelName); - p->pOffset = pOffset; p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->pSrc = pSrc; @@ -3632,9 +3887,8 @@ static int flattenSubquery( if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; p->pPrior = pNew; - SELECTTRACE(2,pParse,p, - ("compound-subquery flattener creates %s.%p as peer\n", - pNew->zSelName, pNew)); + SELECTTRACE(2,pParse,p,("compound-subquery flattener" + " creates %u as peer\n",pNew->selId)); } if( db->mallocFailed ) return 1; } @@ -3768,7 +4022,6 @@ static int flattenSubquery( pOrderBy->a[i].u.x.iOrderByCol = 0; } assert( pParent->pOrderBy==0 ); - assert( pSub->pPrior==0 ); pParent->pOrderBy = pOrderBy; pSub->pOrderBy = 0; } @@ -3776,18 +4029,7 @@ static int flattenSubquery( if( isLeftJoin>0 ){ setJoinExpr(pWhere, iNewParent); } - if( subqueryIsAgg ){ - assert( pParent->pHaving==0 ); - pParent->pHaving = pParent->pWhere; - pParent->pWhere = pWhere; - pParent->pHaving = sqlite3ExprAnd(db, - sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving - ); - assert( pParent->pGroupBy==0 ); - pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); - }else{ - pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); - } + pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); if( db->mallocFailed==0 ){ SubstContext x; x.pParse = pParse; @@ -3831,7 +4073,168 @@ static int flattenSubquery( } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ +/* +** A structure to keep track of all of the column values that fixed to +** a known value due to WHERE clause constraints of the form COLUMN=VALUE. +*/ +typedef struct WhereConst WhereConst; +struct WhereConst { + Parse *pParse; /* Parsing context */ + int nConst; /* Number for COLUMN=CONSTANT terms */ + int nChng; /* Number of times a constant is propagated */ + Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ +}; +/* +** Add a new entry to the pConst object +*/ +static void constInsert( + WhereConst *pConst, + Expr *pColumn, + Expr *pValue +){ + + pConst->nConst++; + pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, + pConst->nConst*2*sizeof(Expr*)); + if( pConst->apExpr==0 ){ + pConst->nConst = 0; + }else{ + if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft; + pConst->apExpr[pConst->nConst*2-2] = pColumn; + pConst->apExpr[pConst->nConst*2-1] = pValue; + } +} + +/* +** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE +** is a constant expression and where the term must be true because it +** is part of the AND-connected terms of the expression. For each term +** found, add it to the pConst structure. +*/ +static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ + Expr *pRight, *pLeft; + if( pExpr==0 ) return; + if( ExprHasProperty(pExpr, EP_FromJoin) ) return; + if( pExpr->op==TK_AND ){ + findConstInWhere(pConst, pExpr->pRight); + findConstInWhere(pConst, pExpr->pLeft); + return; + } + if( pExpr->op!=TK_EQ ) return; + pRight = pExpr->pRight; + pLeft = pExpr->pLeft; + assert( pRight!=0 ); + assert( pLeft!=0 ); + if( pRight->op==TK_COLUMN + && !ExprHasProperty(pRight, EP_FixedCol) + && sqlite3ExprIsConstant(pLeft) + && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) + ){ + constInsert(pConst, pRight, pLeft); + }else + if( pLeft->op==TK_COLUMN + && !ExprHasProperty(pLeft, EP_FixedCol) + && sqlite3ExprIsConstant(pRight) + && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) + ){ + constInsert(pConst, pLeft, pRight); + } +} + +/* +** This is a Walker expression callback. pExpr is a candidate expression +** to be replaced by a value. If pExpr is equivalent to one of the +** columns named in pWalker->u.pConst, then overwrite it with its +** corresponding value. +*/ +static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ + int i; + WhereConst *pConst; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; + if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue; + pConst = pWalker->u.pConst; + for(i=0; inConst; i++){ + Expr *pColumn = pConst->apExpr[i*2]; + if( pColumn==pExpr ) continue; + if( pColumn->iTable!=pExpr->iTable ) continue; + if( pColumn->iColumn!=pExpr->iColumn ) continue; + /* A match is found. Add the EP_FixedCol property */ + pConst->nChng++; + ExprClearProperty(pExpr, EP_Leaf); + ExprSetProperty(pExpr, EP_FixedCol); + assert( pExpr->pLeft==0 ); + pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); + break; + } + return WRC_Prune; +} + +/* +** The WHERE-clause constant propagation optimization. +** +** If the WHERE clause contains terms of the form COLUMN=CONSTANT or +** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level +** AND-connected terms that are not part of a ON clause from a LEFT JOIN) +** then throughout the query replace all other occurrences of COLUMN +** with CONSTANT within the WHERE clause. +** +** For example, the query: +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b +** +** Is transformed into +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39 +** +** Return true if any transformations where made and false if not. +** +** Implementation note: Constant propagation is tricky due to affinity +** and collating sequence interactions. Consider this example: +** +** CREATE TABLE t1(a INT,b TEXT); +** INSERT INTO t1 VALUES(123,'0123'); +** SELECT * FROM t1 WHERE a=123 AND b=a; +** SELECT * FROM t1 WHERE a=123 AND b=123; +** +** The two SELECT statements above should return different answers. b=a +** is alway true because the comparison uses numeric affinity, but b=123 +** is false because it uses text affinity and '0123' is not the same as '123'. +** To work around this, the expression tree is not actually changed from +** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol +** and the "123" value is hung off of the pLeft pointer. Code generator +** routines know to generate the constant "123" instead of looking up the +** column value. Also, to avoid collation problems, this optimization is +** only attempted if the "a=123" term uses the default BINARY collation. +*/ +static int propagateConstants( + Parse *pParse, /* The parsing context */ + Select *p /* The query in which to propagate constants */ +){ + WhereConst x; + Walker w; + int nChng = 0; + x.pParse = pParse; + do{ + x.nConst = 0; + x.nChng = 0; + x.apExpr = 0; + findConstInWhere(&x, p->pWhere); + if( x.nConst ){ + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = propagateConstantExprRewrite; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = 0; + w.walkerDepth = 0; + w.u.pConst = &x; + sqlite3WalkExpr(&w, p->pWhere); + sqlite3DbFree(x.pParse->db, x.apExpr); + nChng += x.nChng; + } + }while( x.nChng ); + return nChng; +} #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* @@ -3850,21 +4253,39 @@ static int flattenSubquery( ** ** Do not attempt this optimization if: ** -** (1) The inner query is an aggregate. (In that case, we'd really want -** to copy the outer WHERE-clause terms onto the HAVING clause of the -** inner query. But they probably won't help there so do not bother.) +** (1) (** This restriction was removed on 2017-09-29. We used to +** disallow this optimization for aggregate subqueries, but now +** it is allowed by putting the extra terms on the HAVING clause. +** The added HAVING clause is pointless if the subquery lacks +** a GROUP BY clause. But such a HAVING clause is also harmless +** so there does not appear to be any reason to add extra logic +** to suppress it. **) ** ** (2) The inner query is the recursive part of a common table expression. ** ** (3) The inner query has a LIMIT clause (since the changes to the WHERE -** close would change the meaning of the LIMIT). +** clause would change the meaning of the LIMIT). ** -** (4) The inner query is the right operand of a LEFT JOIN. (The caller -** enforces this restriction since this routine does not have enough -** information to know.) +** (4) The inner query is the right operand of a LEFT JOIN and the +** expression to be pushed down does not come from the ON clause +** on that LEFT JOIN. ** ** (5) The WHERE clause expression originates in the ON or USING clause -** of a LEFT JOIN. +** of a LEFT JOIN where iCursor is not the right-hand table of that +** left join. An example: +** +** SELECT * +** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa +** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2) +** LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2); +** +** The correct answer is three rows: (1,1,NULL),(2,2,8),(2,2,9). +** But if the (b2=2) term were to be pushed down into the bb subquery, +** then the (1,1,NULL) row would be suppressed. +** +** (6) The inner query features one or more window-functions (since +** changes to the WHERE clause of the inner query could change the +** window over which window functions are calculated). ** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. @@ -3873,40 +4294,65 @@ static int pushDownWhereTerms( Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ - int iCursor /* Cursor number of the subquery */ + int iCursor, /* Cursor number of the subquery */ + int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */ ){ Expr *pNew; int nChng = 0; - Select *pX; /* For looping over compound SELECTs in pSubq */ if( pWhere==0 ) return 0; - for(pX=pSubq; pX; pX=pX->pPrior){ - if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){ - testcase( pX->selFlags & SF_Aggregate ); - testcase( pX->selFlags & SF_Recursive ); - testcase( pX!=pSubq ); - return 0; /* restrictions (1) and (2) */ + if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin ) return 0; /* restriction (6) */ +#endif + +#ifdef SQLITE_DEBUG + /* Only the first term of a compound can have a WITH clause. But make + ** sure no other terms are marked SF_Recursive in case something changes + ** in the future. + */ + { + Select *pX; + for(pX=pSubq; pX; pX=pX->pPrior){ + assert( (pX->selFlags & (SF_Recursive))==0 ); } } +#endif + if( pSubq->pLimit!=0 ){ return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, + iCursor, isLeftJoin); pWhere = pWhere->pLeft; } - if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */ + if( isLeftJoin + && (ExprHasProperty(pWhere,EP_FromJoin)==0 + || pWhere->iRightJoinTable!=iCursor) + ){ + return 0; /* restriction (4) */ + } + if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){ + return 0; /* restriction (5) */ + } if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); + unsetJoinExpr(pNew, -1); x.pParse = pParse; x.iTable = iCursor; x.iNewTable = iCursor; x.isLeftJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); - pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew); + if( pSubq->selFlags & SF_Aggregate ){ + pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew); + }else{ + pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew); + } pSubq = pSubq->pPrior; } } @@ -3915,42 +4361,44 @@ static int pushDownWhereTerms( #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ /* -** Based on the contents of the AggInfo structure indicated by the first -** argument, this function checks if the following are true: +** The pFunc is the only aggregate function in the query. Check to see +** if the query is a candidate for the min/max optimization. ** -** * the query contains just a single aggregate function, -** * the aggregate function is either min() or max(), and -** * the argument to the aggregate function is a column value. +** If the query is a candidate for the min/max optimization, then set +** *ppMinMax to be an ORDER BY clause to be used for the optimization +** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on +** whether pFunc is a min() or max() function. ** -** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX -** is returned as appropriate. Also, *ppMinMax is set to point to the -** list of arguments passed to the aggregate before returning. +** If the query is not a candidate for the min/max optimization, return +** WHERE_ORDERBY_NORMAL (which must be zero). ** -** Or, if the conditions above are not met, *ppMinMax is set to 0 and -** WHERE_ORDERBY_NORMAL is returned. +** This routine must be called after aggregate functions have been +** located but before their arguments have been subjected to aggregate +** analysis. */ -static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){ - int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ +static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ + int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ + ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ + const char *zFunc; /* Name of aggregate function pFunc */ + ExprList *pOrderBy; + u8 sortOrder; - *ppMinMax = 0; - if( pAggInfo->nFunc==1 ){ - Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */ - ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */ - - assert( pExpr->op==TK_AGG_FUNCTION ); - if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){ - const char *zFunc = pExpr->u.zToken; - if( sqlite3StrICmp(zFunc, "min")==0 ){ - eRet = WHERE_ORDERBY_MIN; - *ppMinMax = pEList; - }else if( sqlite3StrICmp(zFunc, "max")==0 ){ - eRet = WHERE_ORDERBY_MAX; - *ppMinMax = pEList; - } - } + assert( *ppMinMax==0 ); + assert( pFunc->op==TK_AGG_FUNCTION ); + if( pEList==0 || pEList->nExpr!=1 ) return eRet; + zFunc = pFunc->u.zToken; + if( sqlite3StrICmp(zFunc, "min")==0 ){ + eRet = WHERE_ORDERBY_MIN; + sortOrder = SQLITE_SO_ASC; + }else if( sqlite3StrICmp(zFunc, "max")==0 ){ + eRet = WHERE_ORDERBY_MAX; + sortOrder = SQLITE_SO_DESC; + }else{ + return eRet; } - - assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 ); + *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); + assert( pOrderBy!=0 || db->mallocFailed ); + if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder; return eRet; } @@ -4081,7 +4529,6 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ assert( pNew->pPrior!=0 ); pNew->pPrior->pNext = pNew; pNew->pLimit = 0; - pNew->pOffset = 0; return WRC_Continue; } @@ -4234,7 +4681,8 @@ static int withExpand( ); return SQLITE_ERROR; } - assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); + assert( pTab->nTabRef==1 || + ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); pCte->zCteErr = "circular reference: %s"; pSavedWith = pParse->pWith; @@ -4291,7 +4739,7 @@ static int withExpand( */ static void selectPopWith(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; - if( pParse->pWith && p->pPrior==0 ){ + if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){ With *pWith = findRightmost(p)->pWith; if( pWith!=0 ){ assert( pParse->pWith==pWith ); @@ -4303,6 +4751,35 @@ static void selectPopWith(Walker *pWalker, Select *p){ #define selectPopWith 0 #endif +/* +** The SrcList_item structure passed as the second argument represents a +** sub-query in the FROM clause of a SELECT statement. This function +** allocates and populates the SrcList_item.pTab object. If successful, +** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, +** SQLITE_NOMEM. +*/ +int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ + Select *pSel = pFrom->pSelect; + Table *pTab; + + assert( pSel ); + pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); + if( pTab==0 ) return SQLITE_NOMEM; + pTab->nTabRef = 1; + if( pFrom->zAlias ){ + pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); + }else{ + pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId); + } + while( pSel->pPrior ){ pSel = pSel->pPrior; } + sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); + pTab->iPKey = -1; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + pTab->tabFlags |= TF_Ephemeral; + + return SQLITE_OK; +} + /* ** This routine is a Walker callback for "expanding" a SELECT statement. ** "Expanding" means to do the following: @@ -4336,19 +4813,19 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3 *db = pParse->db; Expr *pE, *pRight, *pExpr; u16 selFlags = p->selFlags; + u32 elistFlags = 0; p->selFlags |= SF_Expanded; if( db->mallocFailed ){ return WRC_Abort; } - if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ + assert( p->pSrc!=0 ); + if( (selFlags & SF_Expanded)!=0 ){ return WRC_Prune; } pTabList = p->pSrc; pEList = p->pEList; - if( p->pWith ){ - sqlite3WithPush(pParse, p->pWith, 0); - } + sqlite3WithPush(pParse, p->pWith, 0); /* Make sure cursor numbers have been assigned to all entries in ** the FROM clause of the SELECT statement. @@ -4375,15 +4852,7 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pSel!=0 ); assert( pFrom->pTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; - pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return WRC_Abort; - pTab->nTabRef = 1; - pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); - while( pSel->pPrior ){ pSel = pSel->pPrior; } - sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); - pTab->iPKey = -1; - pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - pTab->tabFlags |= TF_Ephemeral; + if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; #endif }else{ /* An ordinary table or view name in the FROM clause */ @@ -4406,7 +4875,6 @@ static int selectExpander(Walker *pWalker, Select *p){ if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); - sqlite3SelectSetName(pFrom->pSelect, pTab->zName); nCol = pTab->nCol; pTab->nCol = -1; sqlite3WalkSelect(pWalker, pFrom->pSelect); @@ -4444,6 +4912,7 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pE->op!=TK_DOT || pE->pRight!=0 ); assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break; + elistFlags |= pE->flags; } if( knExpr ){ /* @@ -4459,6 +4928,7 @@ static int selectExpander(Walker *pWalker, Select *p){ for(k=0; knExpr; k++){ pE = a[k].pExpr; + elistFlags |= pE->flags; pRight = pE->pRight; assert( pE->op!=TK_DOT || pRight!=0 ); if( pE->op!=TK_ASTERISK @@ -4588,12 +5058,15 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3ExprListDelete(db, pEList); p->pEList = pNew; } -#if SQLITE_MAX_COLUMN - if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many columns in result set"); - return WRC_Abort; + if( p->pEList ){ + if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns in result set"); + return WRC_Abort; + } + if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ + p->selFlags |= SF_ComplexResult; + } } -#endif return WRC_Continue; } @@ -4647,7 +5120,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ Walker w; w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; - if( pParse->hasCompound ){ + if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){ w.xSelectCallback = convertCompoundSelectToSubquery; w.xSelectCallback2 = 0; sqlite3WalkSelect(&w, pSelect); @@ -4679,7 +5152,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ struct SrcList_item *pFrom; assert( p->selFlags & SF_Resolved ); - assert( (p->selFlags & SF_HasTypeInfo)==0 ); + if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; pTabList = p->pSrc; @@ -4735,15 +5208,13 @@ void sqlite3SelectPrep( Select *p, /* The SELECT statement being coded. */ NameContext *pOuterNC /* Name context for container */ ){ - sqlite3 *db; - if( NEVER(p==0) ) return; - db = pParse->db; - if( db->mallocFailed ) return; + assert( p!=0 || pParse->db->mallocFailed ); + if( pParse->db->mallocFailed ) return; if( p->selFlags & SF_HasTypeInfo ) return; sqlite3SelectExpand(pParse, p); - if( pParse->nErr || db->mallocFailed ) return; + if( pParse->nErr || pParse->db->mallocFailed ) return; sqlite3ResolveSelectNames(pParse, p, pOuterNC); - if( pParse->nErr || db->mallocFailed ) return; + if( pParse->nErr || pParse->db->mallocFailed ) return; sqlite3SelectAddTypeInfo(pParse, p); } @@ -4784,7 +5255,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ "argument"); pFunc->iDistinct = -1; }else{ - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0); + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); } @@ -4808,11 +5279,17 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ } } + /* ** Update the accumulator memory cells for an aggregate based on ** the current cursor position. +** +** If regAcc is non-zero and there are no min() or max() aggregates +** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator +** registers i register regAcc contains 0. The caller will take care +** of setting and clearing regAcc. */ -static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ +static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; int regHit = 0; @@ -4855,36 +5332,24 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } - sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem); + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); - sqlite3ExprCacheClear(pParse); } } - - /* Before populating the accumulator registers, clear the column cache. - ** Otherwise, if any of the required column values are already present - ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value - ** to pC->iMem. But by the time the value is used, the original register - ** may have been used, invalidating the underlying buffer holding the - ** text or blob value. See ticket [883034dcb5]. - ** - ** Another solution would be to change the OP_SCopy used to copy cached - ** values to an OP_Copy. - */ + if( regHit==0 && pAggInfo->nAccumulator ){ + regHit = regAcc; + } if( regHit ){ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } - sqlite3ExprCacheClear(pParse); for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); } pAggInfo->directMode = 0; - sqlite3ExprCacheClear(pParse); if( addrHitTest ){ sqlite3VdbeJumpHere(v, addrHitTest); } @@ -4902,28 +5367,17 @@ static void explainSimpleCount( ){ if( pParse->explain==2 ){ int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); - char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", + sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s", pTab->zName, bCover ? " USING COVERING INDEX " : "", bCover ? pIdx->zName : "" ); - sqlite3VdbeAddOp4( - pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC - ); } } #else # define explainSimpleCount(a,b,c) #endif -/* -** Context object for havingToWhereExprCb(). -*/ -struct HavingToWhereCtx { - Expr **ppWhere; - ExprList *pGroupBy; -}; - /* ** sqlite3WalkExpr() callback used by havingToWhere(). ** @@ -4937,15 +5391,16 @@ struct HavingToWhereCtx { */ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op!=TK_AND ){ - struct HavingToWhereCtx *p = pWalker->u.pHavingCtx; - if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){ + Select *pS = pWalker->u.pSelect; + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){ sqlite3 *db = pWalker->pParse->db; Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0); if( pNew ){ - Expr *pWhere = *(p->ppWhere); + Expr *pWhere = pS->pWhere; SWAP(Expr, *pNew, *pExpr); pNew = sqlite3ExprAnd(db, pWhere, pNew); - *(p->ppWhere) = pNew; + pS->pWhere = pNew; + pWalker->eCode = 1; } } return WRC_Prune; @@ -4968,23 +5423,19 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ ** entirely of constants and expressions that are also GROUP BY terms that ** use the "BINARY" collation sequence. */ -static void havingToWhere( - Parse *pParse, - ExprList *pGroupBy, - Expr *pHaving, - Expr **ppWhere -){ - struct HavingToWhereCtx sCtx; +static void havingToWhere(Parse *pParse, Select *p){ Walker sWalker; - - sCtx.ppWhere = ppWhere; - sCtx.pGroupBy = pGroupBy; - memset(&sWalker, 0, sizeof(sWalker)); sWalker.pParse = pParse; sWalker.xExprCallback = havingToWhereExprCb; - sWalker.u.pHavingCtx = &sCtx; - sqlite3WalkExpr(&sWalker, pHaving); + sWalker.u.pSelect = p; + sqlite3WalkExpr(&sWalker, p->pHaving); +#if SELECTTRACE_ENABLED + if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ + SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif } /* @@ -5028,6 +5479,7 @@ static struct SrcList_item *isSelfJoinView( ** The transformation only works if all of the following are true: ** ** * The subquery is a UNION ALL of two or more terms +** * The subquery does not have a LIMIT clause ** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries ** * The outer query is a simple count(*) ** @@ -5038,24 +5490,25 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ Expr *pExpr; Expr *pCount; sqlite3 *db; - if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate query */ + if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ pExpr = p->pEList->a[0].pExpr; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ - if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Must be count() */ + if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ - if( p->pSrc->nSrc!=1 ) return 0; /* One table in the FROM clause */ + if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ pSub = p->pSrc->a[0].pSelect; if( pSub==0 ) return 0; /* The FROM is a subquery */ - if( pSub->pPrior==0 ) return 0; /* Must be a compound subquery */ + if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */ do{ if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ if( pSub->pWhere ) return 0; /* No WHERE clause */ + if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ - pSub = pSub->pPrior; /* Repeat over compound terms */ + pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); - /* If we reach this point, that means it is OK to perform the transformation */ + /* If we reach this point then it is OK to perform the transformation */ db = pParse->db; pCount = pExpr; @@ -5130,21 +5583,18 @@ int sqlite3Select( AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ sqlite3 *db; /* The database connection */ - -#ifndef SQLITE_OMIT_EXPLAIN - int iRestoreSelectId = pParse->iSelectId; - pParse->iSelectId = pParse->iNextSelectId++; -#endif + ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */ + u8 minMaxFlag; /* Flag for min/max queries */ db = pParse->db; + v = sqlite3GetVdbe(pParse); if( p==0 || db->mallocFailed || pParse->nErr ){ return 1; } if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; memset(&sAggInfo, 0, sizeof(sAggInfo)); #if SELECTTRACE_ENABLED - pParse->nSelectIndent++; - SELECTTRACE(1,pParse,p, ("begin processing:\n")); + SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } @@ -5166,37 +5616,60 @@ int sqlite3Select( p->selFlags &= ~SF_Distinct; } sqlite3SelectPrep(pParse, p, 0); - memset(&sSort, 0, sizeof(sSort)); - sSort.pOrderBy = p->pOrderBy; - pTabList = p->pSrc; if( pParse->nErr || db->mallocFailed ){ goto select_end; } assert( p->pEList!=0 ); - isAgg = (p->selFlags & SF_Aggregate)!=0; #if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ - SELECTTRACE(0x100,pParse,p, ("after name resolution:\n")); + if( sqlite3SelectTrace & 0x104 ){ + SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif - /* Get a pointer the VDBE under construction, allocating a new VDBE if one - ** does not already exist */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto select_end; if( pDest->eDest==SRT_Output ){ generateColumnNames(pParse, p); } - /* Try to flatten subqueries in the FROM clause up into the main query +#ifndef SQLITE_OMIT_WINDOWFUNC + if( sqlite3WindowRewrite(pParse, p) ){ + goto select_end; + } +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x108 ){ + SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif +#endif /* SQLITE_OMIT_WINDOWFUNC */ + pTabList = p->pSrc; + isAgg = (p->selFlags & SF_Aggregate)!=0; + memset(&sSort, 0, sizeof(sSort)); + sSort.pOrderBy = p->pOrderBy; + + /* Try to various optimizations (flattening subqueries, and strength + ** reduction of join operators) in the FROM clause up into the main query */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && inSrc; i++){ struct SrcList_item *pItem = &pTabList->a[i]; Select *pSub = pItem->pSelect; - int isAggSub; Table *pTab = pItem->pTab; + + /* Convert LEFT JOIN into JOIN if there are terms of the right table + ** of the LEFT JOIN used in the WHERE clause. + */ + if( (pItem->fg.jointype & JT_LEFT)!=0 + && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) + && OptimizationEnabled(db, SQLITE_SimplifyJoin) + ){ + SELECTTRACE(0x100,pParse,p, + ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); + pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); + unsetJoinExpr(p->pWhere, pItem->iCursor); + } + + /* No futher action if this term of the FROM clause is no a subquery */ if( pSub==0 ) continue; /* Catch mismatch in the declared columns of a view and the number of @@ -5207,13 +5680,45 @@ int sqlite3Select( goto select_end; } - isAggSub = (pSub->selFlags & SF_Aggregate)!=0; - if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ + /* Do not try to flatten an aggregate subquery. + ** + ** Flattening an aggregate subquery is only possible if the outer query + ** is not a join. But if the outer query is not a join, then the subquery + ** will be implemented as a co-routine and there is no advantage to + ** flattening in that case. + */ + if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; + assert( pSub->pGroupBy==0 ); + + /* If the outer query contains a "complex" result set (that is, + ** if the result set of the outer query uses functions or subqueries) + ** and if the subquery contains an ORDER BY clause and if + ** it will be implemented as a co-routine, then do not flatten. This + ** restriction allows SQL constructs like this: + ** + ** SELECT expensive_function(x) + ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10); + ** + ** The expensive_function() is only computed on the 10 rows that + ** are output, rather than every row of the table. + ** + ** The requirement that the outer query have a complex result set + ** means that flattening does occur on simpler SQL constraints without + ** the expensive_function() like: + ** + ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10); + */ + if( pSub->pOrderBy!=0 + && i==0 + && (p->selFlags & SF_ComplexResult)!=0 + && (pTabList->nSrc==1 + || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) + ){ + continue; + } + + if( flattenSubquery(pParse, p, i, isAgg) ){ /* This subquery can be absorbed into its parent. */ - if( isAggSub ){ - isAgg = 1; - p->selFlags |= SF_Aggregate; - } i = -1; } pTabList = p->pSrc; @@ -5230,15 +5735,46 @@ int sqlite3Select( */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); - explainSetInteger(pParse->iSelectId, iRestoreSelectId); #if SELECTTRACE_ENABLED - SELECTTRACE(1,pParse,p,("end compound-select processing\n")); - pParse->nSelectIndent--; + SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); + } #endif + if( p->pNext==0 ) ExplainQueryPlanPop(pParse); return rc; } #endif + /* Do the WHERE-clause constant propagation optimization if this is + ** a join. No need to speed time on this operation for non-join queries + ** as the equivalent optimization will be handled by query planner in + ** sqlite3WhereBegin(). + */ + if( pTabList->nSrc>1 + && OptimizationEnabled(db, SQLITE_PropagateConst) + && propagateConstants(pParse, p) + ){ +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + }else{ + SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n")); + } + +#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION + if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) + && countOfViewOptimization(pParse, p) + ){ + if( db->mallocFailed ) goto select_end; + pEList = p->pEList; + pTabList = p->pSrc; + } +#endif + /* For each term in the FROM clause, do two things: ** (1) Authorized unreferenced tables ** (2) Generate code for all sub-queries @@ -5247,10 +5783,14 @@ int sqlite3Select( struct SrcList_item *pItem = &pTabList->a[i]; SelectDest dest; Select *pSub; +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + const char *zSavedAuthContext; +#endif - /* Issue SQLITE_READ authorizations with a fake column name for any tables that - ** are referenced but from which no values are extracted. Examples of where these - ** kinds of null SQLITE_READ authorizations would occur: + /* Issue SQLITE_READ authorizations with a fake column name for any + ** tables that are referenced but from which no values are extracted. + ** Examples of where these kinds of null SQLITE_READ authorizations + ** would occur: ** ** SELECT count(*) FROM t1; -- SQLITE_READ t1."" ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2."" @@ -5258,10 +5798,10 @@ int sqlite3Select( ** The fake column name is an empty string. It is possible for a table to ** have a column named by the empty string, in which case there is no way to ** distinguish between an unreferenced table and an actual reference to the - ** "" column. The original design was for the fake column name to be a NULL, + ** "" column. The original design was for the fake column name to be a NULL, ** which would be unambiguous. But legacy authorization callbacks might - ** assume the column name is non-NULL and segfault. The use of an empty string - ** for the fake column name seems safer. + ** assume the column name is non-NULL and segfault. The use of an empty + ** string for the fake column name seems safer. */ if( pItem->colUsed==0 ){ sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); @@ -5302,27 +5842,29 @@ int sqlite3Select( /* Make copies of constant WHERE-clause terms in the outer query down ** inside the subquery. This can help the subquery to run more efficiently. */ - if( (pItem->fg.jointype & JT_OUTER)==0 - && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor) + if( OptimizationEnabled(db, SQLITE_PushDown) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, + (pItem->fg.jointype & JT_OUTER)!=0) ){ #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ - SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n")); + SELECTTRACE(0x100,pParse,p, + ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif + }else{ + SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); } + zSavedAuthContext = pParse->zAuthContext; + pParse->zAuthContext = pItem->zName; + /* Generate code to implement the subquery ** - ** The subquery is implemented as a co-routine if all of these are true: - ** (1) The subquery is guaranteed to be the outer loop (so that it - ** does not need to be computed more than once) - ** (2) The ALL keyword after SELECT is omitted. (Applications are - ** allowed to say "SELECT ALL" instead of just "SELECT" to disable - ** the use of co-routines.) - ** (3) Co-routines are not disabled using sqlite3_test_control() - ** with SQLITE_TESTCTRL_OPTIMIZATIONS. + ** The subquery is implemented as a co-routine if the subquery is + ** guaranteed to be the outer loop (so that it does not need to be + ** computed more than once) ** ** TODO: Are there other reasons beside (1) to use a co-routine ** implementation? @@ -5330,19 +5872,18 @@ int sqlite3Select( if( i==0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ - && (p->selFlags & SF_All)==0 /* (2) */ - && OptimizationEnabled(db, SQLITE_SubqCoroutine) /* (3) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; + pItem->regReturn = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); VdbeComment((v, "%s", pItem->pTab->zName)); pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); - explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); + ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId)); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; @@ -5377,12 +5918,11 @@ int sqlite3Select( pPrior = isSelfJoinView(pTabList, pItem); if( pPrior ){ sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); - explainSetInteger(pItem->iSelectId, pPrior->iSelectId); assert( pPrior->pSelect!=0 ); pSub->nSelectRow = pPrior->pSelect->nSelectRow; }else{ sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); sqlite3Select(pParse, pSub, &dest); } pItem->pTab->nRowLogEst = pSub->nSelectRow; @@ -5394,6 +5934,7 @@ int sqlite3Select( } if( db->mallocFailed ) goto select_end; pParse->nHeight -= sqlite3SelectExprHeight(p); + pParse->zAuthContext = zSavedAuthContext; #endif } @@ -5412,16 +5953,6 @@ int sqlite3Select( } #endif -#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION - if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) - && countOfViewOptimization(pParse, p) - ){ - if( db->mallocFailed ) goto select_end; - pEList = p->pEList; - pTabList = p->pSrc; - } -#endif - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and ** if the select-list is the same as the ORDER BY list, then this query ** can be rewritten as a GROUP BY. In other words, this: @@ -5465,7 +5996,8 @@ int sqlite3Select( */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; - pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr); + pKeyInfo = sqlite3KeyInfoFromExprList( + pParse, sSort.pOrderBy, 0, pEList->nExpr); sSort.iECursor = pParse->nTab++; sSort.addrSortIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, @@ -5499,9 +6031,9 @@ int sqlite3Select( if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, - sDistinct.tabTnct, 0, 0, - (char*)keyInfoFromExprList(pParse, p->pEList,0,0), - P4_KEYINFO); + sDistinct.tabTnct, 0, 0, + (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), + P4_KEYINFO); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; }else{ @@ -5510,11 +6042,19 @@ int sqlite3Select( if( !isAgg && pGroupBy==0 ){ /* No aggregate functions and no GROUP BY clause */ - u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); + u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) + | (p->selFlags & SF_FixedLimit); +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin = p->pWin; /* Master window object (or NULL) */ + if( pWin ){ + sqlite3WindowCodeInit(pParse, pWin); + } +#endif assert( WHERE_USE_LIMIT==SF_FixedLimit ); - wctrlFlags |= p->selFlags & SF_FixedLimit; + /* Begin the database scan. */ + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, p->pEList, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; @@ -5526,7 +6066,7 @@ int sqlite3Select( } if( sSort.pOrderBy ){ sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); - sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo); + sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ sSort.pOrderBy = 0; } @@ -5540,14 +6080,37 @@ int sqlite3Select( sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); } - /* Use the standard inner loop. */ - selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest, - sqlite3WhereContinueLabel(pWInfo), - sqlite3WhereBreakLabel(pWInfo)); + assert( p->pEList==pEList ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + int addrGosub = sqlite3VdbeMakeLabel(v); + int iCont = sqlite3VdbeMakeLabel(v); + int iBreak = sqlite3VdbeMakeLabel(v); + int regGosub = ++pParse->nMem; - /* End the database scan loop. - */ - sqlite3WhereEnd(pWInfo); + sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); + + sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + sqlite3VdbeResolveLabel(v, addrGosub); + VdbeNoopComment((v, "inner-loop subroutine")); + sSort.labelOBLopt = 0; + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp1(v, OP_Return, regGosub); + VdbeComment((v, "end inner-loop subroutine")); + sqlite3VdbeResolveLabel(v, iBreak); + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + /* Use the standard inner loop. */ + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, + sqlite3WhereContinueLabel(pWInfo), + sqlite3WhereBreakLabel(pWInfo)); + + /* End the database scan loop. + */ + sqlite3WhereEnd(pWInfo); + } }else{ /* This case when there exist aggregate functions or a GROUP BY clause ** or both */ @@ -5606,7 +6169,8 @@ int sqlite3Select( memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; - sNC.pAggInfo = &sAggInfo; + sNC.uNC.pAggInfo = &sAggInfo; + VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) sAggInfo.mnReg = pParse->nMem+1; sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; sAggInfo.pGroupBy = pGroupBy; @@ -5615,12 +6179,19 @@ int sqlite3Select( if( pHaving ){ if( pGroupBy ){ assert( pWhere==p->pWhere ); - havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere); + assert( pHaving==p->pHaving ); + assert( pGroupBy==p->pGroupBy ); + havingToWhere(pParse, p); pWhere = p->pWhere; } sqlite3ExprAnalyzeAggregates(&sNC, pHaving); } sAggInfo.nAccumulator = sAggInfo.nColumn; + if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){ + minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy); + }else{ + minMaxFlag = WHERE_ORDERBY_NORMAL; + } for(i=0; inMem; if( db->mallocFailed ) goto select_end; +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x400 ){ + int ii; + SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n")); + sqlite3TreeViewSelect(0, p, 0); + for(ii=0; iinTab++; - pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn); + pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn); addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO); @@ -5669,8 +6258,6 @@ int sqlite3Select( pParse->nMem += pGroupBy->nExpr; sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); VdbeComment((v, "clear abort flag")); - sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); - VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); /* Begin a loop that will extract all source rows in GROUP BY order. @@ -5679,6 +6266,7 @@ int sqlite3Select( ** in the right order to begin with. */ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 ); @@ -5715,15 +6303,14 @@ int sqlite3Select( } } regBase = sqlite3GetTempRange(pParse, nCol); - sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; for(i=0; iiSorterColumn>=j ){ int r1 = j + regBase; - sqlite3ExprCodeGetColumnToReg(pParse, - pCol->pTab, pCol->iColumn, pCol->iTable, r1); + sqlite3ExprCodeGetColumnOfTable(v, + pCol->pTab, pCol->iTable, pCol->iColumn, r1); j++; } } @@ -5739,8 +6326,6 @@ int sqlite3Select( sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); sAggInfo.useSortingIdx = 1; - sqlite3ExprCacheClear(pParse); - } /* If the index or temporary table used by the GROUP BY sort @@ -5763,7 +6348,6 @@ int sqlite3Select( ** from the previous row currently stored in a0, a1, a2... */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); - sqlite3ExprCacheClear(pParse); if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut, sortPTab); @@ -5802,7 +6386,7 @@ int sqlite3Select( ** the current row */ sqlite3VdbeJumpHere(v, addr1); - updateAccumulator(pParse, &sAggInfo); + updateAccumulator(pParse, iUseFlag, &sAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); @@ -5844,7 +6428,7 @@ int sqlite3Select( sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); finalizeAggFunctions(pParse, &sAggInfo); sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, -1, &sSort, + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, addrOutputRow+1, addrSetAbort); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); @@ -5854,11 +6438,12 @@ int sqlite3Select( */ sqlite3VdbeResolveLabel(v, addrReset); resetAccumulator(pParse, &sAggInfo); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp1(v, OP_Return, regReset); } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { - ExprList *pDel = 0; #ifndef SQLITE_OMIT_BTREECOUNT Table *pTab; if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){ @@ -5920,67 +6505,50 @@ int sqlite3Select( }else #endif /* SQLITE_OMIT_BTREECOUNT */ { - /* Check if the query is of one of the following forms: - ** - ** SELECT min(x) FROM ... - ** SELECT max(x) FROM ... - ** - ** If it is, then ask the code in where.c to attempt to sort results - ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. - ** If where.c is able to produce results sorted in this order, then - ** add vdbe code to break out of the processing loop after the - ** first iteration (since the first iteration of the loop is - ** guaranteed to operate on the row with the minimum or maximum - ** value of x, the only row required). - ** - ** A special flag must be passed to sqlite3WhereBegin() to slightly - ** modify behavior as follows: - ** - ** + If the query is a "SELECT min(x)", then the loop coded by - ** where.c should not iterate over any values with a NULL value - ** for x. - ** - ** + The optimizer code in where.c (the thing that decides which - ** index or indices to use) should place a different priority on - ** satisfying the 'ORDER BY' clause than it does in other cases. - ** Refer to code and comments in where.c for details. - */ - ExprList *pMinMax = 0; - u8 flag = WHERE_ORDERBY_NORMAL; - - assert( p->pGroupBy==0 ); - assert( flag==0 ); - if( p->pHaving==0 ){ - flag = minMaxQuery(&sAggInfo, &pMinMax); - } - assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) ); + int regAcc = 0; /* "populate accumulators" flag */ - if( flag ){ - pMinMax = sqlite3ExprListDup(db, pMinMax, 0); - pDel = pMinMax; - assert( db->mallocFailed || pMinMax!=0 ); - if( !db->mallocFailed ){ - pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; - pMinMax->a[0].pExpr->op = TK_COLUMN; + /* If there are accumulator registers but no min() or max() functions, + ** allocate register regAcc. Register regAcc will contain 0 the first + ** time the inner loop runs, and 1 thereafter. The code generated + ** by updateAccumulator() only updates the accumulator registers if + ** regAcc contains 0. */ + if( sAggInfo.nAccumulator ){ + for(i=0; ifuncFlags&SQLITE_FUNC_NEEDCOLL ) break; + } + if( i==sAggInfo.nFunc ){ + regAcc = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); } } - + /* This case runs if the aggregate has no GROUP BY clause. The ** processing is much simpler since there is only a single row ** of output. */ + assert( p->pGroupBy==0 ); resetAccumulator(pParse, &sAggInfo); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0); + + /* If this query is a candidate for the min/max optimization, then + ** minMaxFlag will have been previously set to either + ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will + ** be an appropriate ORDER BY expression for the optimization. + */ + assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); + assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); + + SELECTTRACE(1,pParse,p,("WhereBegin\n")); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, + 0, minMaxFlag, 0); if( pWInfo==0 ){ - sqlite3ExprListDelete(db, pDel); goto select_end; } - updateAccumulator(pParse, &sAggInfo); - assert( pMinMax==0 || pMinMax->nExpr==1 ); + updateAccumulator(pParse, regAcc, &sAggInfo); + if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); if( sqlite3WhereIsOrdered(pWInfo)>0 ){ sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); VdbeComment((v, "%s() by index", - (flag==WHERE_ORDERBY_MIN?"min":"max"))); + (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max"))); } sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, &sAggInfo); @@ -5988,9 +6556,8 @@ int sqlite3Select( sSort.pOrderBy = 0; sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, + selectInnerLoop(pParse, p, -1, 0, 0, pDest, addrEnd, addrEnd); - sqlite3ExprListDelete(db, pDel); } sqlite3VdbeResolveLabel(v, addrEnd); @@ -6006,6 +6573,7 @@ int sqlite3Select( if( sSort.pOrderBy ){ explainTempTable(pParse, sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); + assert( p->pEList==pEList ); generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); } @@ -6021,13 +6589,15 @@ int sqlite3Select( ** successful coding of the SELECT. */ select_end: - explainSetInteger(pParse->iSelectId, iRestoreSelectId); - + sqlite3ExprListDelete(db, pMinMaxOrderBy); sqlite3DbFree(db, sAggInfo.aCol); sqlite3DbFree(db, sAggInfo.aFunc); #if SELECTTRACE_ENABLED - SELECTTRACE(1,pParse,p,("end processing\n")); - pParse->nSelectIndent--; + SELECTTRACE(0x1,pParse,p,("end processing\n")); + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); + } #endif + ExplainQueryPlanPop(pParse); return rc; } diff --git a/src/shell.c b/src/shell.c deleted file mode 100644 index eaefe62012..0000000000 --- a/src/shell.c +++ /dev/null @@ -1,8398 +0,0 @@ -/* DO NOT EDIT! -** This file is automatically generated by the script in the canonical -** SQLite source tree at tool/mkshellc.tcl. That script combines source -** code from various constituent source files of SQLite into this single -** "shell.c" file used to implement the SQLite command-line shell. -** -** Most of the code found below comes from the "src/shell.c.in" file in -** the canonical SQLite source tree. That main file contains "INCLUDE" -** lines that specify other files in the canonical source tree that are -** inserted to getnerate this complete program source file. -** -** The code from multiple files is combined into this single "shell.c" -** source file to help make the command-line program easier to compile. -** -** To modify this program, get a copy of the canonical SQLite source tree, -** edit the src/shell.c.in" and/or some of the other files that are included -** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script. -*/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code to implement the "sqlite" command line -** utility for accessing SQLite databases. -*/ -#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) -/* This needs to come before any includes for MSVC compiler */ -#define _CRT_SECURE_NO_WARNINGS -#endif - -/* -** Warning pragmas copied from msvc.h in the core. -*/ -#if defined(_MSC_VER) -#pragma warning(disable : 4054) -#pragma warning(disable : 4055) -#pragma warning(disable : 4100) -#pragma warning(disable : 4127) -#pragma warning(disable : 4130) -#pragma warning(disable : 4152) -#pragma warning(disable : 4189) -#pragma warning(disable : 4206) -#pragma warning(disable : 4210) -#pragma warning(disable : 4232) -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) -#pragma warning(disable : 4306) -#pragma warning(disable : 4702) -#pragma warning(disable : 4706) -#endif /* defined(_MSC_VER) */ - -/* -** No support for loadable extensions in VxWorks. -*/ -#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION -# define SQLITE_OMIT_LOAD_EXTENSION 1 -#endif - -/* -** Enable large-file support for fopen() and friends on unix. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - -#include -#include -#include -#include -#include "sqlite3.h" -#if SQLITE_USER_AUTHENTICATION -# include "sqlite3userauth.h" -#endif -#include -#include - -#if !defined(_WIN32) && !defined(WIN32) -# include -# if !defined(__RTP__) && !defined(_WRS_KERNEL) -# include -# endif -# include -# include -#endif - -#if HAVE_READLINE -# include -# include -#endif - -#if HAVE_EDITLINE -# include -#endif - -#if HAVE_EDITLINE || HAVE_READLINE - -# define shell_add_history(X) add_history(X) -# define shell_read_history(X) read_history(X) -# define shell_write_history(X) write_history(X) -# define shell_stifle_history(X) stifle_history(X) -# define shell_readline(X) readline(X) - -#elif HAVE_LINENOISE - -# include "linenoise.h" -# define shell_add_history(X) linenoiseHistoryAdd(X) -# define shell_read_history(X) linenoiseHistoryLoad(X) -# define shell_write_history(X) linenoiseHistorySave(X) -# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) -# define shell_readline(X) linenoise(X) - -#else - -# define shell_read_history(X) -# define shell_write_history(X) -# define shell_stifle_history(X) - -# define SHELL_USE_LOCAL_GETLINE 1 -#endif - - -#if defined(_WIN32) || defined(WIN32) -# include -# include -# define isatty(h) _isatty(h) -# ifndef access -# define access(f,m) _access((f),(m)) -# endif -# undef popen -# define popen _popen -# undef pclose -# define pclose _pclose -#else - /* Make sure isatty() has a prototype. */ - extern int isatty(int); - -# if !defined(__RTP__) && !defined(_WRS_KERNEL) - /* popen and pclose are not C89 functions and so are - ** sometimes omitted from the header */ - extern FILE *popen(const char*,const char*); - extern int pclose(FILE*); -# else -# define SQLITE_OMIT_POPEN 1 -# endif -#endif - -#if defined(_WIN32_WCE) -/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() - * thus we always assume that we have a console. That can be - * overridden with the -batch command line option. - */ -#define isatty(x) 1 -#endif - -/* ctype macros that work with signed characters */ -#define IsSpace(X) isspace((unsigned char)X) -#define IsDigit(X) isdigit((unsigned char)X) -#define ToLower(X) (char)tolower((unsigned char)X) - -#if defined(_WIN32) || defined(WIN32) -#include - -/* string conversion routines only needed on Win32 */ -extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); -extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); -extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); -extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); -#endif - -/* On Windows, we normally run with output mode of TEXT so that \n characters -** are automatically translated into \r\n. However, this behavior needs -** to be disabled in some cases (ex: when generating CSV output and when -** rendering quoted strings that contain \n characters). The following -** routines take care of that. -*/ -#if defined(_WIN32) || defined(WIN32) -static void setBinaryMode(FILE *file, int isOutput){ - if( isOutput ) fflush(file); - _setmode(_fileno(file), _O_BINARY); -} -static void setTextMode(FILE *file, int isOutput){ - if( isOutput ) fflush(file); - _setmode(_fileno(file), _O_TEXT); -} -#else -# define setBinaryMode(X,Y) -# define setTextMode(X,Y) -#endif - - -/* True if the timer is enabled */ -static int enableTimer = 0; - -/* 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>=2 && clockVfs->xCurrentTimeInt64!=0 ){ - clockVfs->xCurrentTimeInt64(clockVfs, &t); - }else{ - double r; - clockVfs->xCurrentTime(clockVfs, &r); - t = (sqlite3_int64)(r*86400000.0); - } - return t; -} - -#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) -#include -#include - -/* VxWorks does not support getrusage() as far as we can determine */ -#if defined(_WRS_KERNEL) || defined(__RTP__) -struct rusage { - struct timeval ru_utime; /* user CPU time used */ - struct timeval ru_stime; /* system CPU time used */ -}; -#define getrusage(A,B) memset(B,0,sizeof(*B)) -#endif - -/* Saved resource information for the beginning of an operation */ -static struct rusage sBegin; /* CPU time at start */ -static sqlite3_int64 iBegin; /* Wall-clock time at start */ - -/* -** Begin timing an operation -*/ -static void beginTimer(void){ - if( enableTimer ){ - getrusage(RUSAGE_SELF, &sBegin); - iBegin = timeOfDay(); - } -} - -/* Return the difference of two time_structs in seconds */ -static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ - return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + - (double)(pEnd->tv_sec - pStart->tv_sec); -} - -/* -** Print the timing results. -*/ -static void endTimer(void){ - if( enableTimer ){ - sqlite3_int64 iEnd = timeOfDay(); - struct rusage sEnd; - getrusage(RUSAGE_SELF, &sEnd); - printf("Run Time: real %.3f user %f sys %f\n", - (iEnd - iBegin)*0.001, - timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), - timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); - } -} - -#define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() -#define HAS_TIMER 1 - -#elif (defined(_WIN32) || defined(WIN32)) - -/* Saved resource information for the beginning of an operation */ -static HANDLE hProcess; -static FILETIME ftKernelBegin; -static FILETIME ftUserBegin; -static sqlite3_int64 ftWallBegin; -typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, - LPFILETIME, LPFILETIME); -static GETPROCTIMES getProcessTimesAddr = NULL; - -/* -** Check to see if we have timer support. Return 1 if necessary -** support found (or found previously). -*/ -static int hasTimer(void){ - if( getProcessTimesAddr ){ - return 1; - } else { - /* GetProcessTimes() isn't supported in WIN95 and some other Windows - ** versions. See if the version we are running on has it, and if it - ** does, save off a pointer to it and the current process handle. - */ - hProcess = GetCurrentProcess(); - if( hProcess ){ - HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); - if( NULL != hinstLib ){ - getProcessTimesAddr = - (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); - if( NULL != getProcessTimesAddr ){ - return 1; - } - FreeLibrary(hinstLib); - } - } - } - return 0; -} - -/* -** Begin timing an operation -*/ -static void beginTimer(void){ - if( enableTimer && getProcessTimesAddr ){ - FILETIME ftCreation, ftExit; - getProcessTimesAddr(hProcess,&ftCreation,&ftExit, - &ftKernelBegin,&ftUserBegin); - ftWallBegin = timeOfDay(); - } -} - -/* Return the difference of two FILETIME structs in seconds */ -static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ - sqlite_int64 i64Start = *((sqlite_int64 *) pStart); - sqlite_int64 i64End = *((sqlite_int64 *) pEnd); - return (double) ((i64End - i64Start) / 10000000.0); -} - -/* -** Print the timing results. -*/ -static void endTimer(void){ - if( enableTimer && getProcessTimesAddr){ - FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; - sqlite3_int64 ftWallEnd = timeOfDay(); - getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); - printf("Run Time: real %.3f user %f sys %f\n", - (ftWallEnd - ftWallBegin)*0.001, - timeDiff(&ftUserBegin, &ftUserEnd), - timeDiff(&ftKernelBegin, &ftKernelEnd)); - } -} - -#define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() -#define HAS_TIMER hasTimer() - -#else -#define BEGIN_TIMER -#define END_TIMER -#define HAS_TIMER 0 -#endif - -/* -** Used to prevent warnings about unused parameters -*/ -#define UNUSED_PARAMETER(x) (void)(x) - -/* -** If the following flag is set, then command execution stops -** at an error if we are not interactive. -*/ -static int bail_on_error = 0; - -/* -** Threat stdin as an interactive input if the following variable -** is true. Otherwise, assume stdin is connected to a file or pipe. -*/ -static int stdin_is_interactive = 1; - -/* -** On Windows systems we have to know if standard output is a console -** in order to translate UTF-8 into MBCS. The following variable is -** true if translation is required. -*/ -static int stdout_is_console = 1; - -/* -** The following is the open SQLite database. We make a pointer -** to this database a static variable so that it can be accessed -** by the SIGINT handler to interrupt database processing. -*/ -static sqlite3 *globalDb = 0; - -/* -** True if an interrupt (Control-C) has been received. -*/ -static volatile int seenInterrupt = 0; - -/* -** This is the name of our program. It is set in main(), used -** in a number of other places, mostly for error messages. -*/ -static char *Argv0; - -/* -** Prompt strings. Initialized in main. Settable with -** .prompt main continue -*/ -static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ -static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ - -/* -** Render output like fprintf(). Except, if the output is going to the -** console and if this is running on a Windows machine, translate the -** output from UTF-8 into MBCS. -*/ -#if defined(_WIN32) || defined(WIN32) -void utf8_printf(FILE *out, const char *zFormat, ...){ - va_list ap; - va_start(ap, zFormat); - if( stdout_is_console && (out==stdout || out==stderr) ){ - char *z1 = sqlite3_vmprintf(zFormat, ap); - char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); - sqlite3_free(z1); - fputs(z2, out); - sqlite3_free(z2); - }else{ - vfprintf(out, zFormat, ap); - } - va_end(ap); -} -#elif !defined(utf8_printf) -# define utf8_printf fprintf -#endif - -/* -** Render output like fprintf(). This should not be used on anything that -** includes string formatting (e.g. "%s"). -*/ -#if !defined(raw_printf) -# define raw_printf fprintf -#endif - -/* -** Write I/O traces to the following stream. -*/ -#ifdef SQLITE_ENABLE_IOTRACE -static FILE *iotrace = 0; -#endif - -/* -** This routine works like printf in that its first argument is a -** format string and subsequent arguments are values to be substituted -** in place of % fields. The result of formatting this string -** is written to iotrace. -*/ -#ifdef SQLITE_ENABLE_IOTRACE -static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ - va_list ap; - char *z; - if( iotrace==0 ) return; - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - utf8_printf(iotrace, "%s", z); - sqlite3_free(z); -} -#endif - -/* -** Output string zUtf to stream pOut as w characters. If w is negative, -** then right-justify the text. W is the width in UTF-8 characters, not -** in bytes. This is different from the %*.*s specification in printf -** since with %*.*s the width is measured in bytes, not characters. -*/ -static void utf8_width_print(FILE *pOut, int w, const char *zUtf){ - int i; - int n; - int aw = w<0 ? -w : w; - char zBuf[1000]; - if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3; - for(i=n=0; zUtf[i]; i++){ - if( (zUtf[i]&0xc0)!=0x80 ){ - n++; - if( n==aw ){ - do{ i++; }while( (zUtf[i]&0xc0)==0x80 ); - break; - } - } - } - if( n>=aw ){ - utf8_printf(pOut, "%.*s", i, zUtf); - }else if( w<0 ){ - utf8_printf(pOut, "%*s%s", aw-n, "", zUtf); - }else{ - utf8_printf(pOut, "%s%*s", zUtf, aw-n, ""); - } -} - - -/* -** Determines if a string is a number of not. -*/ -static int isNumber(const char *z, int *realnum){ - if( *z=='-' || *z=='+' ) z++; - if( !IsDigit(*z) ){ - return 0; - } - z++; - if( realnum ) *realnum = 0; - while( IsDigit(*z) ){ z++; } - if( *z=='.' ){ - z++; - if( !IsDigit(*z) ) return 0; - while( IsDigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z++; - if( *z=='+' || *z=='-' ) z++; - if( !IsDigit(*z) ) return 0; - while( IsDigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - return *z==0; -} - -/* -** Compute a string length that is limited to what can be stored in -** lower 30 bits of a 32-bit signed integer. -*/ -static int strlen30(const char *z){ - const char *z2 = z; - while( *z2 ){ z2++; } - return 0x3fffffff & (int)(z2 - z); -} - -/* -** Return the length of a string in characters. Multibyte UTF8 characters -** count as a single character. -*/ -static int strlenChar(const char *z){ - int n = 0; - while( *z ){ - if( (0xc0&*(z++))!=0x80 ) n++; - } - return n; -} - -/* -** This routine reads a line of text from FILE in, stores -** the text in memory obtained from malloc() and returns a pointer -** to the text. NULL is returned at end of file, or if malloc() -** fails. -** -** If zLine is not NULL then it is a malloced buffer returned from -** a previous call to this routine that may be reused. -*/ -static char *local_getline(char *zLine, FILE *in){ - int nLine = zLine==0 ? 0 : 100; - int n = 0; - - while( 1 ){ - if( n+100>nLine ){ - nLine = nLine*2 + 100; - zLine = realloc(zLine, nLine); - if( zLine==0 ) return 0; - } - if( fgets(&zLine[n], nLine - n, in)==0 ){ - if( n==0 ){ - free(zLine); - return 0; - } - zLine[n] = 0; - break; - } - while( zLine[n] ) n++; - if( n>0 && zLine[n-1]=='\n' ){ - n--; - if( n>0 && zLine[n-1]=='\r' ) n--; - zLine[n] = 0; - break; - } - } -#if defined(_WIN32) || defined(WIN32) - /* For interactive input on Windows systems, translate the - ** multi-byte characterset characters into UTF-8. */ - if( stdin_is_interactive && in==stdin ){ - char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); - if( zTrans ){ - int nTrans = strlen30(zTrans)+1; - if( nTrans>nLine ){ - zLine = realloc(zLine, nTrans); - if( zLine==0 ){ - sqlite3_free(zTrans); - return 0; - } - } - memcpy(zLine, zTrans, nTrans); - sqlite3_free(zTrans); - } - } -#endif /* defined(_WIN32) || defined(WIN32) */ - return zLine; -} - -/* -** Retrieve a single line of input text. -** -** If in==0 then read from standard input and prompt before each line. -** If isContinuation is true, then a continuation prompt is appropriate. -** If isContinuation is zero, then the main prompt should be used. -** -** If zPrior is not NULL then it is a buffer from a prior call to this -** routine that can be reused. -** -** The result is stored in space obtained from malloc() and must either -** be freed by the caller or else passed back into this routine via the -** zPrior argument for reuse. -*/ -static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ - char *zPrompt; - char *zResult; - if( in!=0 ){ - zResult = local_getline(zPrior, in); - }else{ - zPrompt = isContinuation ? continuePrompt : mainPrompt; -#if SHELL_USE_LOCAL_GETLINE - printf("%s", zPrompt); - fflush(stdout); - zResult = local_getline(zPrior, stdin); -#else - free(zPrior); - zResult = shell_readline(zPrompt); - if( zResult && *zResult ) shell_add_history(zResult); -#endif - } - return zResult; -} -/* -** A variable length string to which one can append text. -*/ -typedef struct ShellText ShellText; -struct ShellText { - char *z; - int n; - int nAlloc; -}; - -/* -** Initialize and destroy a ShellText object -*/ -static void initText(ShellText *p){ - memset(p, 0, sizeof(*p)); -} -static void freeText(ShellText *p){ - free(p->z); - initText(p); -} - -/* zIn is either a pointer to a NULL-terminated string in memory obtained -** from malloc(), or a NULL pointer. The string pointed to by zAppend is -** added to zIn, and the result returned in memory obtained from malloc(). -** zIn, if it was not NULL, is freed. -** -** If the third argument, quote, is not '\0', then it is used as a -** quote character for zAppend. -*/ -static void appendText(ShellText *p, char const *zAppend, char quote){ - int len; - int i; - int nAppend = strlen30(zAppend); - - len = nAppend+p->n+1; - if( quote ){ - len += 2; - for(i=0; in+len>=p->nAlloc ){ - p->nAlloc = p->nAlloc*2 + len + 20; - p->z = realloc(p->z, p->nAlloc); - if( p->z==0 ){ - memset(p, 0, sizeof(*p)); - return; - } - } - - if( quote ){ - char *zCsr = p->z+p->n; - *zCsr++ = quote; - for(i=0; in = (int)(zCsr - p->z); - *zCsr = '\0'; - }else{ - memcpy(p->z+p->n, zAppend, nAppend); - p->n += nAppend; - p->z[p->n] = '\0'; - } -} - -/* -** Attempt to determine if identifier zName needs to be quoted, either -** because it contains non-alphanumeric characters, or because it is an -** SQLite keyword. Be conservative in this estimate: When in doubt assume -** that quoting is required. -** -** Return '"' if quoting is required. Return 0 if no quoting is required. -*/ -static char quoteChar(const char *zName){ - /* All SQLite keywords, in alphabetical order */ - static const char *azKeywords[] = { - "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", - "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", - "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", - "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", - "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", - "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", - "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", - "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", - "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", - "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", - "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", - "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", - "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", - "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", - "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", - "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", - "WITH", "WITHOUT", - }; - int i, lwr, upr, mid, c; - if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; - for(i=0; zName[i]; i++){ - if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; - } - lwr = 0; - upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; - while( lwr<=upr ){ - mid = (lwr+upr)/2; - c = sqlite3_stricmp(azKeywords[mid], zName); - if( c==0 ) return '"'; - if( c<0 ){ - lwr = mid+1; - }else{ - upr = mid-1; - } - } - return 0; -} - -/* -** SQL function: shell_add_schema(S,X) -** -** Add the schema name X to the CREATE statement in S and return the result. -** Examples: -** -** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x); -** -** Also works on -** -** CREATE INDEX -** CREATE UNIQUE INDEX -** CREATE VIEW -** CREATE TRIGGER -** CREATE VIRTUAL TABLE -** -** This UDF is used by the .schema command to insert the schema name of -** attached databases into the middle of the sqlite_master.sql field. -*/ -static void shellAddSchemaName( - sqlite3_context *pCtx, - int nVal, - sqlite3_value **apVal -){ - static const char *aPrefix[] = { - "TABLE", - "INDEX", - "UNIQUE INDEX", - "VIEW", - "TRIGGER", - "VIRTUAL TABLE" - }; - int i = 0; - const char *zIn = (const char*)sqlite3_value_text(apVal[0]); - const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); - assert( nVal==2 ); - if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ - for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){ - int n = strlen30(aPrefix[i]); - if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){ - char cQuote = quoteChar(zSchema); - char *z; - if( cQuote ){ - z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8); - }else{ - z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8); - } - sqlite3_result_text(pCtx, z, -1, sqlite3_free); - return; - } - } - } - sqlite3_result_value(pCtx, apVal[0]); -} - -/* -** The source code for several run-time loadable extensions is inserted -** below by the ../tool/mkshellc.tcl script. Before processing that included -** code, we need to override some macros to make the included program code -** work here in the middle of this regular program. -*/ -#define SQLITE_EXTENSION_INIT1 -#define SQLITE_EXTENSION_INIT2(X) (void)(X) - -/************************* Begin ../ext/misc/shathree.c ******************/ -/* -** 2017-03-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This SQLite extension implements a functions that compute SHA1 hashes. -** Two SQL functions are implemented: -** -** sha3(X,SIZE) -** sha3_query(Y,SIZE) -** -** The sha3(X) function computes the SHA3 hash of the input X, or NULL if -** X is NULL. -** -** The sha3_query(Y) function evalutes all queries in the SQL statements of Y -** and returns a hash of their results. -** -** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm -** is used. If SIZE is included it must be one of the integers 224, 256, -** 384, or 512, to determine SHA3 hash variant that is computed. -*/ -SQLITE_EXTENSION_INIT1 -#include -#include -#include -typedef sqlite3_uint64 u64; - -/****************************************************************************** -** The Hash Engine -*/ -/* -** Macros to determine whether the machine is big or little endian, -** and whether or not that determination is run-time or compile-time. -** -** For best performance, an attempt is made to guess at the byte-order -** using C-preprocessor macros. If that is unsuccessful, or if -** -DSHA3_BYTEORDER=0 is set, then byte-order is determined -** at run-time. -*/ -#ifndef SHA3_BYTEORDER -# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ - defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__arm__) -# define SHA3_BYTEORDER 1234 -# elif defined(sparc) || defined(__ppc__) -# define SHA3_BYTEORDER 4321 -# else -# define SHA3_BYTEORDER 0 -# endif -#endif - - -/* -** State structure for a SHA3 hash in progress -*/ -typedef struct SHA3Context SHA3Context; -struct SHA3Context { - union { - u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ - unsigned char x[1600]; /* ... or 1600 bytes */ - } u; - unsigned nRate; /* Bytes of input accepted per Keccak iteration */ - unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ - unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ -}; - -/* -** A single step of the Keccak mixing function for a 1600-bit state -*/ -static void KeccakF1600Step(SHA3Context *p){ - int i; - u64 B0, B1, B2, B3, B4; - u64 C0, C1, C2, C3, C4; - u64 D0, D1, D2, D3, D4; - static const u64 RC[] = { - 0x0000000000000001ULL, 0x0000000000008082ULL, - 0x800000000000808aULL, 0x8000000080008000ULL, - 0x000000000000808bULL, 0x0000000080000001ULL, - 0x8000000080008081ULL, 0x8000000000008009ULL, - 0x000000000000008aULL, 0x0000000000000088ULL, - 0x0000000080008009ULL, 0x000000008000000aULL, - 0x000000008000808bULL, 0x800000000000008bULL, - 0x8000000000008089ULL, 0x8000000000008003ULL, - 0x8000000000008002ULL, 0x8000000000000080ULL, - 0x000000000000800aULL, 0x800000008000000aULL, - 0x8000000080008081ULL, 0x8000000000008080ULL, - 0x0000000080000001ULL, 0x8000000080008008ULL - }; -# define A00 (p->u.s[0]) -# define A01 (p->u.s[1]) -# define A02 (p->u.s[2]) -# define A03 (p->u.s[3]) -# define A04 (p->u.s[4]) -# define A10 (p->u.s[5]) -# define A11 (p->u.s[6]) -# define A12 (p->u.s[7]) -# define A13 (p->u.s[8]) -# define A14 (p->u.s[9]) -# define A20 (p->u.s[10]) -# define A21 (p->u.s[11]) -# define A22 (p->u.s[12]) -# define A23 (p->u.s[13]) -# define A24 (p->u.s[14]) -# define A30 (p->u.s[15]) -# define A31 (p->u.s[16]) -# define A32 (p->u.s[17]) -# define A33 (p->u.s[18]) -# define A34 (p->u.s[19]) -# define A40 (p->u.s[20]) -# define A41 (p->u.s[21]) -# define A42 (p->u.s[22]) -# define A43 (p->u.s[23]) -# define A44 (p->u.s[24]) -# define ROL64(a,x) ((a<>(64-x))) - - for(i=0; i<24; i+=4){ - C0 = A00^A10^A20^A30^A40; - C1 = A01^A11^A21^A31^A41; - C2 = A02^A12^A22^A32^A42; - C3 = A03^A13^A23^A33^A43; - C4 = A04^A14^A24^A34^A44; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); - - B0 = (A00^D0); - B1 = ROL64((A11^D1), 44); - B2 = ROL64((A22^D2), 43); - B3 = ROL64((A33^D3), 21); - B4 = ROL64((A44^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i]; - A11 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); - - B2 = ROL64((A20^D0), 3); - B3 = ROL64((A31^D1), 45); - B4 = ROL64((A42^D2), 61); - B0 = ROL64((A03^D3), 28); - B1 = ROL64((A14^D4), 20); - A20 = B0 ^((~B1)& B2 ); - A31 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); - - B4 = ROL64((A40^D0), 18); - B0 = ROL64((A01^D1), 1); - B1 = ROL64((A12^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A34^D4), 8); - A40 = B0 ^((~B1)& B2 ); - A01 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); - - B1 = ROL64((A10^D0), 36); - B2 = ROL64((A21^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A43^D3), 56); - B0 = ROL64((A04^D4), 27); - A10 = B0 ^((~B1)& B2 ); - A21 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); - - B3 = ROL64((A30^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A02^D2), 62); - B1 = ROL64((A13^D3), 55); - B2 = ROL64((A24^D4), 39); - A30 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); - - C0 = A00^A20^A40^A10^A30; - C1 = A11^A31^A01^A21^A41; - C2 = A22^A42^A12^A32^A02; - C3 = A33^A03^A23^A43^A13; - C4 = A44^A14^A34^A04^A24; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); - - B0 = (A00^D0); - B1 = ROL64((A31^D1), 44); - B2 = ROL64((A12^D2), 43); - B3 = ROL64((A43^D3), 21); - B4 = ROL64((A24^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i+1]; - A31 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); - - B2 = ROL64((A40^D0), 3); - B3 = ROL64((A21^D1), 45); - B4 = ROL64((A02^D2), 61); - B0 = ROL64((A33^D3), 28); - B1 = ROL64((A14^D4), 20); - A40 = B0 ^((~B1)& B2 ); - A21 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); - - B4 = ROL64((A30^D0), 18); - B0 = ROL64((A11^D1), 1); - B1 = ROL64((A42^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A04^D4), 8); - A30 = B0 ^((~B1)& B2 ); - A11 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); - - B1 = ROL64((A20^D0), 36); - B2 = ROL64((A01^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A13^D3), 56); - B0 = ROL64((A44^D4), 27); - A20 = B0 ^((~B1)& B2 ); - A01 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); - - B3 = ROL64((A10^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A22^D2), 62); - B1 = ROL64((A03^D3), 55); - B2 = ROL64((A34^D4), 39); - A10 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); - - C0 = A00^A40^A30^A20^A10; - C1 = A31^A21^A11^A01^A41; - C2 = A12^A02^A42^A32^A22; - C3 = A43^A33^A23^A13^A03; - C4 = A24^A14^A04^A44^A34; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); - - B0 = (A00^D0); - B1 = ROL64((A21^D1), 44); - B2 = ROL64((A42^D2), 43); - B3 = ROL64((A13^D3), 21); - B4 = ROL64((A34^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i+2]; - A21 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); - - B2 = ROL64((A30^D0), 3); - B3 = ROL64((A01^D1), 45); - B4 = ROL64((A22^D2), 61); - B0 = ROL64((A43^D3), 28); - B1 = ROL64((A14^D4), 20); - A30 = B0 ^((~B1)& B2 ); - A01 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); - - B4 = ROL64((A10^D0), 18); - B0 = ROL64((A31^D1), 1); - B1 = ROL64((A02^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A44^D4), 8); - A10 = B0 ^((~B1)& B2 ); - A31 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); - - B1 = ROL64((A40^D0), 36); - B2 = ROL64((A11^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A03^D3), 56); - B0 = ROL64((A24^D4), 27); - A40 = B0 ^((~B1)& B2 ); - A11 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); - - B3 = ROL64((A20^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A12^D2), 62); - B1 = ROL64((A33^D3), 55); - B2 = ROL64((A04^D4), 39); - A20 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); - - C0 = A00^A30^A10^A40^A20; - C1 = A21^A01^A31^A11^A41; - C2 = A42^A22^A02^A32^A12; - C3 = A13^A43^A23^A03^A33; - C4 = A34^A14^A44^A24^A04; - D0 = C4^ROL64(C1, 1); - D1 = C0^ROL64(C2, 1); - D2 = C1^ROL64(C3, 1); - D3 = C2^ROL64(C4, 1); - D4 = C3^ROL64(C0, 1); - - B0 = (A00^D0); - B1 = ROL64((A01^D1), 44); - B2 = ROL64((A02^D2), 43); - B3 = ROL64((A03^D3), 21); - B4 = ROL64((A04^D4), 14); - A00 = B0 ^((~B1)& B2 ); - A00 ^= RC[i+3]; - A01 = B1 ^((~B2)& B3 ); - A02 = B2 ^((~B3)& B4 ); - A03 = B3 ^((~B4)& B0 ); - A04 = B4 ^((~B0)& B1 ); - - B2 = ROL64((A10^D0), 3); - B3 = ROL64((A11^D1), 45); - B4 = ROL64((A12^D2), 61); - B0 = ROL64((A13^D3), 28); - B1 = ROL64((A14^D4), 20); - A10 = B0 ^((~B1)& B2 ); - A11 = B1 ^((~B2)& B3 ); - A12 = B2 ^((~B3)& B4 ); - A13 = B3 ^((~B4)& B0 ); - A14 = B4 ^((~B0)& B1 ); - - B4 = ROL64((A20^D0), 18); - B0 = ROL64((A21^D1), 1); - B1 = ROL64((A22^D2), 6); - B2 = ROL64((A23^D3), 25); - B3 = ROL64((A24^D4), 8); - A20 = B0 ^((~B1)& B2 ); - A21 = B1 ^((~B2)& B3 ); - A22 = B2 ^((~B3)& B4 ); - A23 = B3 ^((~B4)& B0 ); - A24 = B4 ^((~B0)& B1 ); - - B1 = ROL64((A30^D0), 36); - B2 = ROL64((A31^D1), 10); - B3 = ROL64((A32^D2), 15); - B4 = ROL64((A33^D3), 56); - B0 = ROL64((A34^D4), 27); - A30 = B0 ^((~B1)& B2 ); - A31 = B1 ^((~B2)& B3 ); - A32 = B2 ^((~B3)& B4 ); - A33 = B3 ^((~B4)& B0 ); - A34 = B4 ^((~B0)& B1 ); - - B3 = ROL64((A40^D0), 41); - B4 = ROL64((A41^D1), 2); - B0 = ROL64((A42^D2), 62); - B1 = ROL64((A43^D3), 55); - B2 = ROL64((A44^D4), 39); - A40 = B0 ^((~B1)& B2 ); - A41 = B1 ^((~B2)& B3 ); - A42 = B2 ^((~B3)& B4 ); - A43 = B3 ^((~B4)& B0 ); - A44 = B4 ^((~B0)& B1 ); - } -} - -/* -** Initialize a new hash. iSize determines the size of the hash -** in bits and should be one of 224, 256, 384, or 512. Or iSize -** can be zero to use the default hash size of 256 bits. -*/ -static void SHA3Init(SHA3Context *p, int iSize){ - memset(p, 0, sizeof(*p)); - if( iSize>=128 && iSize<=512 ){ - p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; - }else{ - p->nRate = (1600 - 2*256)/8; - } -#if SHA3_BYTEORDER==1234 - /* Known to be little-endian at compile-time. No-op */ -#elif SHA3_BYTEORDER==4321 - p->ixMask = 7; /* Big-endian */ -#else - { - static unsigned int one = 1; - if( 1==*(unsigned char*)&one ){ - /* Little endian. No byte swapping. */ - p->ixMask = 0; - }else{ - /* Big endian. Byte swap. */ - p->ixMask = 7; - } - } -#endif -} - -/* -** Make consecutive calls to the SHA3Update function to add new content -** to the hash -*/ -static void SHA3Update( - SHA3Context *p, - const unsigned char *aData, - unsigned int nData -){ - unsigned int i = 0; -#if SHA3_BYTEORDER==1234 - if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ - for(; i+7u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; - p->nLoaded += 8; - if( p->nLoaded>=p->nRate ){ - KeccakF1600Step(p); - p->nLoaded = 0; - } - } - } -#endif - for(; iu.x[p->nLoaded] ^= aData[i]; -#elif SHA3_BYTEORDER==4321 - p->u.x[p->nLoaded^0x07] ^= aData[i]; -#else - p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; -#endif - p->nLoaded++; - if( p->nLoaded==p->nRate ){ - KeccakF1600Step(p); - p->nLoaded = 0; - } - } -} - -/* -** After all content has been added, invoke SHA3Final() to compute -** the final hash. The function returns a pointer to the binary -** hash value. -*/ -static unsigned char *SHA3Final(SHA3Context *p){ - unsigned int i; - if( p->nLoaded==p->nRate-1 ){ - const unsigned char c1 = 0x86; - SHA3Update(p, &c1, 1); - }else{ - const unsigned char c2 = 0x06; - const unsigned char c3 = 0x80; - SHA3Update(p, &c2, 1); - p->nLoaded = p->nRate - 1; - SHA3Update(p, &c3, 1); - } - for(i=0; inRate; i++){ - p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; - } - return &p->u.x[p->nRate]; -} -/* End of the hashing logic -*****************************************************************************/ - -/* -** Implementation of the sha3(X,SIZE) function. -** -** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default -** size is 256. If X is a BLOB, it is hashed as is. -** For all other non-NULL types of input, X is converted into a UTF-8 string -** and the string is hashed without the trailing 0x00 terminator. The hash -** of a NULL value is NULL. -*/ -static void sha3Func( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - SHA3Context cx; - int eType = sqlite3_value_type(argv[0]); - int nByte = sqlite3_value_bytes(argv[0]); - int iSize; - if( argc==1 ){ - iSize = 256; - }else{ - iSize = sqlite3_value_int(argv[1]); - if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ - sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " - "384 512", -1); - return; - } - } - if( eType==SQLITE_NULL ) return; - SHA3Init(&cx, iSize); - if( eType==SQLITE_BLOB ){ - SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); - }else{ - SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); - } - sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); -} - -/* Compute a string using sqlite3_vsnprintf() with a maximum length -** of 50 bytes and add it to the hash. -*/ -static void hash_step_vformat( - SHA3Context *p, /* Add content to this context */ - const char *zFormat, - ... -){ - va_list ap; - int n; - char zBuf[50]; - va_start(ap, zFormat); - sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); - va_end(ap); - n = (int)strlen(zBuf); - SHA3Update(p, (unsigned char*)zBuf, n); -} - -/* -** Implementation of the sha3_query(SQL,SIZE) function. -** -** This function compiles and runs the SQL statement(s) given in the -** argument. The results are hashed using a SIZE-bit SHA3. The default -** size is 256. -** -** The format of the byte stream that is hashed is summarized as follows: -** -** S: -** R -** N -** I -** F -** B: -** T: -** -** is the original SQL text for each statement run and is -** the size of that text. The SQL text is UTF-8. A single R character -** occurs before the start of each row. N means a NULL value. -** I mean an 8-byte little-endian integer . F is a floating point -** number with an 8-byte little-endian IEEE floating point value . -** B means blobs of bytes. T means text rendered as -** bytes of UTF-8. The and values are expressed as an ASCII -** text integers. -** -** For each SQL statement in the X input, there is one S segment. Each -** S segment is followed by zero or more R segments, one for each row in the -** result set. After each R, there are one or more N, I, F, B, or T segments, -** one for each column in the result set. Segments are concatentated directly -** with no delimiters of any kind. -*/ -static void sha3QueryFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_context_db_handle(context); - const char *zSql = (const char*)sqlite3_value_text(argv[0]); - sqlite3_stmt *pStmt = 0; - int nCol; /* Number of columns in the result set */ - int i; /* Loop counter */ - int rc; - int n; - const char *z; - SHA3Context cx; - int iSize; - - if( argc==1 ){ - iSize = 256; - }else{ - iSize = sqlite3_value_int(argv[1]); - if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ - sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " - "384 512", -1); - return; - } - } - if( zSql==0 ) return; - SHA3Init(&cx, iSize); - while( zSql[0] ){ - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); - if( rc ){ - char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", - zSql, sqlite3_errmsg(db)); - sqlite3_finalize(pStmt); - sqlite3_result_error(context, zMsg, -1); - sqlite3_free(zMsg); - return; - } - if( !sqlite3_stmt_readonly(pStmt) ){ - char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); - sqlite3_finalize(pStmt); - sqlite3_result_error(context, zMsg, -1); - sqlite3_free(zMsg); - return; - } - nCol = sqlite3_column_count(pStmt); - z = sqlite3_sql(pStmt); - n = (int)strlen(z); - hash_step_vformat(&cx,"S%d:",n); - SHA3Update(&cx,(unsigned char*)z,n); - - /* Compute a hash over the result of the query */ - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - SHA3Update(&cx,(const unsigned char*)"R",1); - for(i=0; i=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'I'; - SHA3Update(&cx, x, 9); - break; - } - case SQLITE_FLOAT: { - sqlite3_uint64 u; - int j; - unsigned char x[9]; - double r = sqlite3_column_double(pStmt,i); - memcpy(&u, &r, 8); - for(j=8; j>=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'F'; - SHA3Update(&cx,x,9); - break; - } - case SQLITE_TEXT: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_text(pStmt, i); - hash_step_vformat(&cx,"T%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - case SQLITE_BLOB: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_blob(pStmt, i); - hash_step_vformat(&cx,"B%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - } - } - } - sqlite3_finalize(pStmt); - } - sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); -} - - -#ifdef _WIN32 -__declspec(dllexport) -#endif -int sqlite3_shathree_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - int rc = SQLITE_OK; - SQLITE_EXTENSION_INIT2(pApi); - (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0, - sha3Func, 0, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0, - sha3Func, 0, 0); - } - if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0, - sha3QueryFunc, 0, 0); - } - if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0, - sha3QueryFunc, 0, 0); - } - return rc; -} - -/************************* End ../ext/misc/shathree.c ********************/ -/************************* Begin ../ext/misc/fileio.c ******************/ -/* -** 2014-06-13 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This SQLite extension implements SQL functions readfile() and -** writefile(). -*/ -SQLITE_EXTENSION_INIT1 -#include - -/* -** 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; - - (void)(argc); /* Unused parameter */ - 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_malloc( nIn ); - if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ - sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); - }else{ - sqlite3_free(pBuf); - } - fclose(in); -} - -/* -** Implementation of the "writefile(X,Y)" SQL function. The argument Y -** is written into file X. The number of bytes written is returned. Or -** NULL is returned if something goes wrong, such as being unable to open -** file X for writing. -*/ -static void writefileFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - FILE *out; - const char *z; - sqlite3_int64 rc; - const char *zFile; - - (void)(argc); /* Unused parameter */ - zFile = (const char*)sqlite3_value_text(argv[0]); - if( zFile==0 ) return; - out = fopen(zFile, "wb"); - if( out==0 ) return; - z = (const char*)sqlite3_value_blob(argv[1]); - if( z==0 ){ - rc = 0; - }else{ - rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); - } - fclose(out); - sqlite3_result_int64(context, rc); -} - - -#ifdef _WIN32 -__declspec(dllexport) -#endif -int sqlite3_fileio_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - int rc = SQLITE_OK; - SQLITE_EXTENSION_INIT2(pApi); - (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, - readfileFunc, 0, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, - writefileFunc, 0, 0); - } - return rc; -} - -/************************* End ../ext/misc/fileio.c ********************/ -/************************* Begin ../ext/misc/completion.c ******************/ -/* -** 2017-07-10 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file implements an eponymous virtual table that returns suggested -** completions for a partial SQL input. -** -** Suggested usage: -** -** SELECT DISTINCT candidate COLLATE nocase -** FROM completion($prefix,$wholeline) -** ORDER BY 1; -** -** The two query parameters are optional. $prefix is the text of the -** current word being typed and that is to be completed. $wholeline is -** the complete input line, used for context. -** -** The raw completion() table might return the same candidate multiple -** times, for example if the same column name is used to two or more -** tables. And the candidates are returned in an arbitrary order. Hence, -** the DISTINCT and ORDER BY are recommended. -** -** This virtual table operates at the speed of human typing, and so there -** is no attempt to make it fast. Even a slow implementation will be much -** faster than any human can type. -** -*/ -SQLITE_EXTENSION_INIT1 -#include -#include -#include - -#ifndef SQLITE_OMIT_VIRTUALTABLE - -/* completion_vtab is a subclass of sqlite3_vtab which will -** serve as the underlying representation of a completion virtual table -*/ -typedef struct completion_vtab completion_vtab; -struct completion_vtab { - sqlite3_vtab base; /* Base class - must be first */ - sqlite3 *db; /* Database connection for this completion vtab */ -}; - -/* completion_cursor is a subclass of sqlite3_vtab_cursor which will -** serve as the underlying representation of a cursor that scans -** over rows of the result -*/ -typedef struct completion_cursor completion_cursor; -struct completion_cursor { - sqlite3_vtab_cursor base; /* Base class - must be first */ - sqlite3 *db; /* Database connection for this cursor */ - int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */ - char *zPrefix; /* The prefix for the word we want to complete */ - char *zLine; /* The whole that we want to complete */ - const char *zCurrentRow; /* Current output row */ - sqlite3_stmt *pStmt; /* Current statement */ - sqlite3_int64 iRowid; /* The rowid */ - int ePhase; /* Current phase */ - int j; /* inter-phase counter */ -}; - -/* Values for ePhase: -*/ -#define COMPLETION_FIRST_PHASE 1 -#define COMPLETION_KEYWORDS 1 -#define COMPLETION_PRAGMAS 2 -#define COMPLETION_FUNCTIONS 3 -#define COMPLETION_COLLATIONS 4 -#define COMPLETION_INDEXES 5 -#define COMPLETION_TRIGGERS 6 -#define COMPLETION_DATABASES 7 -#define COMPLETION_TABLES 8 -#define COMPLETION_COLUMNS 9 -#define COMPLETION_MODULES 10 -#define COMPLETION_EOF 11 - -/* -** The completionConnect() method is invoked to create a new -** completion_vtab that describes the completion virtual table. -** -** Think of this routine as the constructor for completion_vtab objects. -** -** All this routine needs to do is: -** -** (1) Allocate the completion_vtab object and initialize all fields. -** -** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the -** result set of queries against completion will look like. -*/ -static int completionConnect( - sqlite3 *db, - void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVtab, - char **pzErr -){ - completion_vtab *pNew; - int rc; - - (void)(pAux); /* Unused parameter */ - (void)(argc); /* Unused parameter */ - (void)(argv); /* Unused parameter */ - (void)(pzErr); /* Unused parameter */ - -/* Column numbers */ -#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ -#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ -#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ -#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */ - - rc = sqlite3_declare_vtab(db, - "CREATE TABLE x(" - " candidate TEXT," - " prefix TEXT HIDDEN," - " wholeline TEXT HIDDEN," - " phase INT HIDDEN" /* Used for debugging only */ - ")"); - if( rc==SQLITE_OK ){ - pNew = sqlite3_malloc( sizeof(*pNew) ); - *ppVtab = (sqlite3_vtab*)pNew; - if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(*pNew)); - pNew->db = db; - } - return rc; -} - -/* -** This method is the destructor for completion_cursor objects. -*/ -static int completionDisconnect(sqlite3_vtab *pVtab){ - sqlite3_free(pVtab); - return SQLITE_OK; -} - -/* -** Constructor for a new completion_cursor object. -*/ -static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ - completion_cursor *pCur; - pCur = sqlite3_malloc( sizeof(*pCur) ); - if( pCur==0 ) return SQLITE_NOMEM; - memset(pCur, 0, sizeof(*pCur)); - pCur->db = ((completion_vtab*)p)->db; - *ppCursor = &pCur->base; - return SQLITE_OK; -} - -/* -** Reset the completion_cursor. -*/ -static void completionCursorReset(completion_cursor *pCur){ - sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0; - sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0; - sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; - pCur->j = 0; -} - -/* -** Destructor for a completion_cursor. -*/ -static int completionClose(sqlite3_vtab_cursor *cur){ - completionCursorReset((completion_cursor*)cur); - sqlite3_free(cur); - return SQLITE_OK; -} - -/* -** All SQL keywords understood by SQLite -*/ -static const char *completionKwrds[] = { - "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", - "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", - "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", - "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", - "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", - "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", - "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", - "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", - "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", - "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", - "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", - "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", - "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", - "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", - "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", - "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", - "WITH", "WITHOUT", -}; -#define completionKwCount \ - (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0])) - -/* -** Advance a completion_cursor to its next row of output. -** -** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object -** record the current state of the scan. This routine sets ->zCurrentRow -** to the current row of output and then returns. If no more rows remain, -** then ->ePhase is set to COMPLETION_EOF which will signal the virtual -** table that has reached the end of its scan. -** -** The current implementation just lists potential identifiers and -** keywords and filters them by zPrefix. Future enhancements should -** take zLine into account to try to restrict the set of identifiers and -** keywords based on what would be legal at the current point of input. -*/ -static int completionNext(sqlite3_vtab_cursor *cur){ - completion_cursor *pCur = (completion_cursor*)cur; - int eNextPhase = 0; /* Next phase to try if current phase reaches end */ - int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */ - pCur->iRowid++; - while( pCur->ePhase!=COMPLETION_EOF ){ - switch( pCur->ePhase ){ - case COMPLETION_KEYWORDS: { - if( pCur->j >= completionKwCount ){ - pCur->zCurrentRow = 0; - pCur->ePhase = COMPLETION_DATABASES; - }else{ - pCur->zCurrentRow = completionKwrds[pCur->j++]; - } - iCol = -1; - break; - } - case COMPLETION_DATABASES: { - if( pCur->pStmt==0 ){ - sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, - &pCur->pStmt, 0); - } - iCol = 1; - eNextPhase = COMPLETION_TABLES; - break; - } - case COMPLETION_TABLES: { - if( pCur->pStmt==0 ){ - sqlite3_stmt *pS2; - char *zSql = 0; - const char *zSep = ""; - sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); - while( sqlite3_step(pS2)==SQLITE_ROW ){ - const char *zDb = (const char*)sqlite3_column_text(pS2, 1); - zSql = sqlite3_mprintf( - "%z%s" - "SELECT name FROM \"%w\".sqlite_master" - " WHERE type='table'", - zSql, zSep, zDb - ); - if( zSql==0 ) return SQLITE_NOMEM; - zSep = " UNION "; - } - sqlite3_finalize(pS2); - sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); - sqlite3_free(zSql); - } - iCol = 0; - eNextPhase = COMPLETION_COLUMNS; - break; - } - case COMPLETION_COLUMNS: { - if( pCur->pStmt==0 ){ - sqlite3_stmt *pS2; - char *zSql = 0; - const char *zSep = ""; - sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); - while( sqlite3_step(pS2)==SQLITE_ROW ){ - const char *zDb = (const char*)sqlite3_column_text(pS2, 1); - zSql = sqlite3_mprintf( - "%z%s" - "SELECT pti.name FROM \"%w\".sqlite_master AS sm" - " JOIN pragma_table_info(sm.name,%Q) AS pti" - " WHERE sm.type='table'", - zSql, zSep, zDb, zDb - ); - if( zSql==0 ) return SQLITE_NOMEM; - zSep = " UNION "; - } - sqlite3_finalize(pS2); - sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); - sqlite3_free(zSql); - } - iCol = 0; - eNextPhase = COMPLETION_EOF; - break; - } - } - if( iCol<0 ){ - /* This case is when the phase presets zCurrentRow */ - if( pCur->zCurrentRow==0 ) continue; - }else{ - if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){ - /* Extract the next row of content */ - pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol); - }else{ - /* When all rows are finished, advance to the next phase */ - sqlite3_finalize(pCur->pStmt); - pCur->pStmt = 0; - pCur->ePhase = eNextPhase; - continue; - } - } - if( pCur->nPrefix==0 ) break; - if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){ - break; - } - } - - return SQLITE_OK; -} - -/* -** Return values of columns for the row at which the completion_cursor -** is currently pointing. -*/ -static int completionColumn( - sqlite3_vtab_cursor *cur, /* The cursor */ - sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ - int i /* Which column to return */ -){ - completion_cursor *pCur = (completion_cursor*)cur; - switch( i ){ - case COMPLETION_COLUMN_CANDIDATE: { - sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT); - break; - } - case COMPLETION_COLUMN_PREFIX: { - sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT); - break; - } - case COMPLETION_COLUMN_WHOLELINE: { - sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT); - break; - } - case COMPLETION_COLUMN_PHASE: { - sqlite3_result_int(ctx, pCur->ePhase); - break; - } - } - return SQLITE_OK; -} - -/* -** Return the rowid for the current row. In this implementation, the -** rowid is the same as the output value. -*/ -static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ - completion_cursor *pCur = (completion_cursor*)cur; - *pRowid = pCur->iRowid; - return SQLITE_OK; -} - -/* -** Return TRUE if the cursor has been moved off of the last -** row of output. -*/ -static int completionEof(sqlite3_vtab_cursor *cur){ - completion_cursor *pCur = (completion_cursor*)cur; - return pCur->ePhase >= COMPLETION_EOF; -} - -/* -** This method is called to "rewind" the completion_cursor object back -** to the first row of output. This method is always called at least -** once prior to any call to completionColumn() or completionRowid() or -** completionEof(). -*/ -static int completionFilter( - sqlite3_vtab_cursor *pVtabCursor, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv -){ - completion_cursor *pCur = (completion_cursor *)pVtabCursor; - int iArg = 0; - (void)(idxStr); /* Unused parameter */ - (void)(argc); /* Unused parameter */ - completionCursorReset(pCur); - if( idxNum & 1 ){ - pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); - if( pCur->nPrefix>0 ){ - pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); - if( pCur->zPrefix==0 ) return SQLITE_NOMEM; - } - iArg++; - } - if( idxNum & 2 ){ - pCur->nLine = sqlite3_value_bytes(argv[iArg]); - if( pCur->nLine>0 ){ - pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); - if( pCur->zLine==0 ) return SQLITE_NOMEM; - } - iArg++; - } - if( pCur->zLine!=0 && pCur->zPrefix==0 ){ - int i = pCur->nLine; - while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ - i--; - } - pCur->nPrefix = pCur->nLine - i; - if( pCur->nPrefix>0 ){ - pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); - if( pCur->zPrefix==0 ) return SQLITE_NOMEM; - } - } - pCur->iRowid = 0; - pCur->ePhase = COMPLETION_FIRST_PHASE; - return completionNext(pVtabCursor); -} - -/* -** SQLite will invoke this method one or more times while planning a query -** that uses the completion virtual table. This routine needs to create -** a query plan for each invocation and compute an estimated cost for that -** plan. -** -** There are two hidden parameters that act as arguments to the table-valued -** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix" -** is available and bit 1 is set if "wholeline" is available. -*/ -static int completionBestIndex( - sqlite3_vtab *tab, - sqlite3_index_info *pIdxInfo -){ - int i; /* Loop over constraints */ - int idxNum = 0; /* The query plan bitmask */ - int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */ - int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */ - int nArg = 0; /* Number of arguments that completeFilter() expects */ - const struct sqlite3_index_constraint *pConstraint; - - (void)(tab); /* Unused parameter */ - pConstraint = pIdxInfo->aConstraint; - for(i=0; inConstraint; i++, pConstraint++){ - if( pConstraint->usable==0 ) continue; - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; - switch( pConstraint->iColumn ){ - case COMPLETION_COLUMN_PREFIX: - prefixIdx = i; - idxNum |= 1; - break; - case COMPLETION_COLUMN_WHOLELINE: - wholelineIdx = i; - idxNum |= 2; - break; - } - } - if( prefixIdx>=0 ){ - pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg; - pIdxInfo->aConstraintUsage[prefixIdx].omit = 1; - } - if( wholelineIdx>=0 ){ - pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg; - pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1; - } - pIdxInfo->idxNum = idxNum; - pIdxInfo->estimatedCost = (double)5000 - 1000*nArg; - pIdxInfo->estimatedRows = 500 - 100*nArg; - return SQLITE_OK; -} - -/* -** This following structure defines all the methods for the -** completion virtual table. -*/ -static sqlite3_module completionModule = { - 0, /* iVersion */ - 0, /* xCreate */ - completionConnect, /* xConnect */ - completionBestIndex, /* xBestIndex */ - completionDisconnect, /* xDisconnect */ - 0, /* xDestroy */ - completionOpen, /* xOpen - open a cursor */ - completionClose, /* xClose - close a cursor */ - completionFilter, /* xFilter - configure scan constraints */ - completionNext, /* xNext - advance a cursor */ - completionEof, /* xEof - check for end of scan */ - completionColumn, /* xColumn - read data */ - completionRowid, /* xRowid - read data */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindMethod */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0 /* xRollbackTo */ -}; - -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -int sqlite3CompletionVtabInit(sqlite3 *db){ - int rc = SQLITE_OK; -#ifndef SQLITE_OMIT_VIRTUALTABLE - rc = sqlite3_create_module(db, "completion", &completionModule, 0); -#endif - return rc; -} - -#ifdef _WIN32 -__declspec(dllexport) -#endif -int sqlite3_completion_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - int rc = SQLITE_OK; - SQLITE_EXTENSION_INIT2(pApi); - (void)(pzErrMsg); /* Unused parameter */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - rc = sqlite3CompletionVtabInit(db); -#endif - return rc; -} - -/************************* End ../ext/misc/completion.c ********************/ - -#if defined(SQLITE_ENABLE_SESSION) -/* -** State information for a single open session -*/ -typedef struct OpenSession OpenSession; -struct OpenSession { - char *zName; /* Symbolic name for this session */ - int nFilter; /* Number of xFilter rejection GLOB patterns */ - char **azFilter; /* Array of xFilter rejection GLOB patterns */ - sqlite3_session *p; /* The open session */ -}; -#endif - -/* -** Shell output mode information from before ".explain on", -** saved so that it can be restored by ".explain off" -*/ -typedef struct SavedModeInfo SavedModeInfo; -struct SavedModeInfo { - int valid; /* Is there legit data in here? */ - int mode; /* Mode prior to ".explain on" */ - int showHeader; /* The ".header" setting prior to ".explain on" */ - int colWidth[100]; /* Column widths prior to ".explain on" */ -}; - -/* -** State information about the database connection is contained in an -** instance of the following structure. -*/ -typedef struct ShellState ShellState; -struct ShellState { - sqlite3 *db; /* The database */ - int autoExplain; /* Automatically turn on .explain mode */ - int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ - int statsOn; /* True to display memory stats before each finalize */ - int scanstatsOn; /* True to display scan stats before each finalize */ - int outCount; /* Revert to stdout when reaching zero */ - int cnt; /* Number of records displayed so far */ - FILE *out; /* Write results here */ - FILE *traceOut; /* Output for sqlite3_trace() */ - int nErr; /* Number of errors seen */ - int mode; /* An output mode setting */ - int cMode; /* temporary output mode for the current query */ - int normalMode; /* Output mode before ".explain on" */ - int writableSchema; /* True if PRAGMA writable_schema=ON */ - int showHeader; /* True to show column names in List or Column mode */ - int nCheck; /* Number of ".check" commands run */ - unsigned shellFlgs; /* Various flags */ - char *zDestTable; /* Name of destination table when MODE_Insert */ - char zTestcase[30]; /* Name of current test case */ - char colSeparator[20]; /* Column separator character for several modes */ - char rowSeparator[20]; /* Row separator character for MODE_Ascii */ - int colWidth[100]; /* Requested width of each column when in column mode*/ - int actualWidth[100]; /* Actual width of each column */ - char nullValue[20]; /* The text to print when a NULL comes back from - ** the database */ - char outfile[FILENAME_MAX]; /* Filename for *out */ - const char *zDbFilename; /* name of the database file */ - char *zFreeOnClose; /* Filename to free when closing */ - const char *zVfs; /* Name of VFS to use */ - sqlite3_stmt *pStmt; /* Current statement if any. */ - FILE *pLog; /* Write log output here */ - int *aiIndent; /* Array of indents used in MODE_Explain */ - int nIndent; /* Size of array aiIndent[] */ - int iIndent; /* Index of current op in aiIndent[] */ -#if defined(SQLITE_ENABLE_SESSION) - int nSession; /* Number of active sessions */ - OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ -#endif -}; - -/* -** These are the allowed shellFlgs values -*/ -#define SHFLG_Scratch 0x00000001 /* The --scratch option is used */ -#define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */ -#define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ -#define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ -#define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ -#define SHFLG_Newlines 0x00000020 /* .dump --newline flag */ -#define SHFLG_CountChanges 0x00000040 /* .changes setting */ -#define SHFLG_Echo 0x00000080 /* .echo or --echo setting */ - -/* -** Macros for testing and setting shellFlgs -*/ -#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0) -#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) -#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) - -/* -** These are the allowed modes. -*/ -#define MODE_Line 0 /* One column per line. Blank line between records */ -#define MODE_Column 1 /* One record per line in neat columns */ -#define MODE_List 2 /* One record per line with a separator */ -#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ -#define MODE_Html 4 /* Generate an XHTML table */ -#define MODE_Insert 5 /* Generate SQL "insert" statements */ -#define MODE_Quote 6 /* Quote values as for SQL */ -#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */ -#define MODE_Csv 8 /* Quote strings, numbers are plain */ -#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ -#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ -#define MODE_Pretty 11 /* Pretty-print schemas */ - -static const char *modeDescr[] = { - "line", - "column", - "list", - "semi", - "html", - "insert", - "quote", - "tcl", - "csv", - "explain", - "ascii", - "prettyprint", -}; - -/* -** These are the column/row/line separators used by the various -** import/export modes. -*/ -#define SEP_Column "|" -#define SEP_Row "\n" -#define SEP_Tab "\t" -#define SEP_Space " " -#define SEP_Comma "," -#define SEP_CrLf "\r\n" -#define SEP_Unit "\x1F" -#define SEP_Record "\x1E" - -/* -** Number of elements in an array -*/ -#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) - -/* -** A callback for the sqlite3_log() interface. -*/ -static void shellLog(void *pArg, int iErrCode, const char *zMsg){ - ShellState *p = (ShellState*)pArg; - if( p->pLog==0 ) return; - utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg); - fflush(p->pLog); -} - -/* -** Output the given string as a hex-encoded blob (eg. X'1234' ) -*/ -static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ - int i; - char *zBlob = (char *)pBlob; - raw_printf(out,"X'"); - for(i=0; i0 ){ - utf8_printf(out,"%.*s",i,z); - } - if( z[i]=='<' ){ - raw_printf(out,"<"); - }else if( z[i]=='&' ){ - raw_printf(out,"&"); - }else if( z[i]=='>' ){ - raw_printf(out,">"); - }else if( z[i]=='\"' ){ - raw_printf(out,"""); - }else if( z[i]=='\'' ){ - raw_printf(out,"'"); - }else{ - break; - } - z += i + 1; - } -} - -/* -** If a field contains any character identified by a 1 in the following -** array, then the string must be quoted for CSV. -*/ -static const char needCsvQuote[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -/* -** Output a single term of CSV. Actually, p->colSeparator is used for -** the separator, which may or may not be a comma. p->nullValue is -** the null value. Strings are quoted if necessary. The separator -** is only issued if bSep is true. -*/ -static void output_csv(ShellState *p, const char *z, int bSep){ - FILE *out = p->out; - if( z==0 ){ - utf8_printf(out,"%s",p->nullValue); - }else{ - int i; - int nSep = strlen30(p->colSeparator); - for(i=0; z[i]; i++){ - if( needCsvQuote[((unsigned char*)z)[i]] - || (z[i]==p->colSeparator[0] && - (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ - i = 0; - break; - } - } - if( i==0 ){ - putc('"', out); - for(i=0; z[i]; i++){ - if( z[i]=='"' ) putc('"', out); - putc(z[i], out); - } - putc('"', out); - }else{ - utf8_printf(out, "%s", z); - } - } - if( bSep ){ - utf8_printf(p->out, "%s", p->colSeparator); - } -} - -#ifdef SIGINT -/* -** This routine runs when the user presses Ctrl-C -*/ -static void interrupt_handler(int NotUsed){ - UNUSED_PARAMETER(NotUsed); - seenInterrupt++; - if( seenInterrupt>2 ) exit(1); - if( globalDb ) sqlite3_interrupt(globalDb); -} -#endif - -#ifndef SQLITE_OMIT_AUTHORIZATION -/* -** When the ".auth ON" is set, the following authorizer callback is -** invoked. It always returns SQLITE_OK. -*/ -static int shellAuth( - void *pClientData, - int op, - const char *zA1, - const char *zA2, - const char *zA3, - const char *zA4 -){ - ShellState *p = (ShellState*)pClientData; - static const char *azAction[] = { 0, - "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX", - "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW", - "CREATE_TRIGGER", "CREATE_VIEW", "DELETE", - "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX", - "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW", - "DROP_TRIGGER", "DROP_VIEW", "INSERT", - "PRAGMA", "READ", "SELECT", - "TRANSACTION", "UPDATE", "ATTACH", - "DETACH", "ALTER_TABLE", "REINDEX", - "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE", - "FUNCTION", "SAVEPOINT", "RECURSIVE" - }; - int i; - const char *az[4]; - az[0] = zA1; - az[1] = zA2; - az[2] = zA3; - az[3] = zA4; - utf8_printf(p->out, "authorizer: %s", azAction[op]); - for(i=0; i<4; i++){ - raw_printf(p->out, " "); - if( az[i] ){ - output_c_string(p->out, az[i]); - }else{ - raw_printf(p->out, "NULL"); - } - } - raw_printf(p->out, "\n"); - return SQLITE_OK; -} -#endif - -/* -** Print a schema statement. Part of MODE_Semi and MODE_Pretty output. -** -** This routine converts some CREATE TABLE statements for shadow tables -** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. -*/ -static void printSchemaLine(FILE *out, const char *z, const char *zTail){ - if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ - utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); - }else{ - utf8_printf(out, "%s%s", z, zTail); - } -} -static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ - char c = z[n]; - z[n] = 0; - printSchemaLine(out, z, zTail); - z[n] = c; -} - -/* -** This is the callback routine that the shell -** invokes for each row of a query result. -*/ -static int shell_callback( - void *pArg, - int nArg, /* Number of result columns */ - char **azArg, /* Text of each result column */ - char **azCol, /* Column names */ - int *aiType /* Column types */ -){ - int i; - ShellState *p = (ShellState*)pArg; - - switch( p->cMode ){ - case MODE_Line: { - int w = 5; - if( azArg==0 ) break; - for(i=0; iw ) w = len; - } - if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator); - for(i=0; iout,"%*s = %s%s", w, azCol[i], - azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); - } - break; - } - case MODE_Explain: - case MODE_Column: { - static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13}; - const int *colWidth; - int showHdr; - char *rowSep; - if( p->cMode==MODE_Column ){ - colWidth = p->colWidth; - showHdr = p->showHeader; - rowSep = p->rowSeparator; - }else{ - colWidth = aExplainWidths; - showHdr = 1; - rowSep = SEP_Row; - } - if( p->cnt++==0 ){ - for(i=0; icolWidth) ){ - w = colWidth[i]; - }else{ - w = 0; - } - if( w==0 ){ - w = strlenChar(azCol[i] ? azCol[i] : ""); - if( w<10 ) w = 10; - n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue); - if( wactualWidth) ){ - p->actualWidth[i] = w; - } - if( showHdr ){ - utf8_width_print(p->out, w, azCol[i]); - utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " "); - } - } - if( showHdr ){ - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - if( w<0 ) w = -w; - }else{ - w = 10; - } - utf8_printf(p->out,"%-*.*s%s",w,w, - "----------------------------------------------------------" - "----------------------------------------------------------", - i==nArg-1 ? rowSep : " "); - } - } - } - if( azArg==0 ) break; - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - }else{ - w = 10; - } - if( p->cMode==MODE_Explain && azArg[i] && strlenChar(azArg[i])>w ){ - w = strlenChar(azArg[i]); - } - if( i==1 && p->aiIndent && p->pStmt ){ - if( p->iIndentnIndent ){ - utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); - } - p->iIndent++; - } - utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue); - utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " "); - } - break; - } - case MODE_Semi: { /* .schema and .fullschema output */ - printSchemaLine(p->out, azArg[0], ";\n"); - break; - } - case MODE_Pretty: { /* .schema and .fullschema with --indent */ - char *z; - int j; - int nParen = 0; - char cEnd = 0; - char c; - int nLine = 0; - assert( nArg==1 ); - if( azArg[0]==0 ) break; - if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 - || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 - ){ - utf8_printf(p->out, "%s;\n", azArg[0]); - break; - } - z = sqlite3_mprintf("%s", azArg[0]); - j = 0; - for(i=0; IsSpace(z[i]); i++){} - for(; (c = z[i])!=0; i++){ - if( IsSpace(c) ){ - if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; - }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ - j--; - } - z[j++] = c; - } - while( j>0 && IsSpace(z[j-1]) ){ j--; } - z[j] = 0; - if( strlen30(z)>=79 ){ - for(i=j=0; (c = z[i])!=0; i++){ - if( c==cEnd ){ - cEnd = 0; - }else if( c=='"' || c=='\'' || c=='`' ){ - cEnd = c; - }else if( c=='[' ){ - cEnd = ']'; - }else if( c=='(' ){ - nParen++; - }else if( c==')' ){ - nParen--; - if( nLine>0 && nParen==0 && j>0 ){ - printSchemaLineN(p->out, z, j, "\n"); - j = 0; - } - } - z[j++] = c; - if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ - if( c=='\n' ) j--; - printSchemaLineN(p->out, z, j, "\n "); - j = 0; - nLine++; - while( IsSpace(z[i+1]) ){ i++; } - } - } - z[j] = 0; - } - printSchemaLine(p->out, z, ";\n"); - sqlite3_free(z); - break; - } - case MODE_List: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,"%s%s",azCol[i], - i==nArg-1 ? p->rowSeparator : p->colSeparator); - } - } - if( azArg==0 ) break; - for(i=0; inullValue; - utf8_printf(p->out, "%s", z); - if( iout, "%s", p->colSeparator); - }else{ - utf8_printf(p->out, "%s", p->rowSeparator); - } - } - break; - } - case MODE_Html: { - if( p->cnt++==0 && p->showHeader ){ - raw_printf(p->out,""); - for(i=0; iout,""); - output_html_string(p->out, azCol[i]); - raw_printf(p->out,"\n"); - } - raw_printf(p->out,"\n"); - } - if( azArg==0 ) break; - raw_printf(p->out,""); - for(i=0; iout,""); - output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); - raw_printf(p->out,"\n"); - } - raw_printf(p->out,"\n"); - break; - } - case MODE_Tcl: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,azCol[i] ? azCol[i] : ""); - if(iout, "%s", p->colSeparator); - } - utf8_printf(p->out, "%s", p->rowSeparator); - } - if( azArg==0 ) break; - for(i=0; iout, azArg[i] ? azArg[i] : p->nullValue); - if(iout, "%s", p->colSeparator); - } - utf8_printf(p->out, "%s", p->rowSeparator); - break; - } - case MODE_Csv: { - setBinaryMode(p->out, 1); - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout, "%s", p->rowSeparator); - } - if( nArg>0 ){ - for(i=0; iout, "%s", p->rowSeparator); - } - setTextMode(p->out, 1); - break; - } - case MODE_Insert: { - if( azArg==0 ) break; - utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); - if( p->showHeader ){ - raw_printf(p->out,"("); - for(i=0; i0 ) raw_printf(p->out, ","); - if( quoteChar(azCol[i]) ){ - char *z = sqlite3_mprintf("\"%w\"", azCol[i]); - utf8_printf(p->out, "%s", z); - sqlite3_free(z); - }else{ - raw_printf(p->out, "%s", azCol[i]); - } - } - raw_printf(p->out,")"); - } - p->cnt++; - for(i=0; iout, i>0 ? "," : " VALUES("); - if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - utf8_printf(p->out,"NULL"); - }else if( aiType && aiType[i]==SQLITE_TEXT ){ - if( ShellHasFlag(p, SHFLG_Newlines) ){ - output_quoted_string(p->out, azArg[i]); - }else{ - output_quoted_escaped_string(p->out, azArg[i]); - } - }else if( aiType && aiType[i]==SQLITE_INTEGER ){ - utf8_printf(p->out,"%s", azArg[i]); - }else if( aiType && aiType[i]==SQLITE_FLOAT ){ - char z[50]; - double r = sqlite3_column_double(p->pStmt, i); - sqlite3_snprintf(50,z,"%!.20g", r); - raw_printf(p->out, "%s", z); - }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ - const void *pBlob = sqlite3_column_blob(p->pStmt, i); - int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_hex_blob(p->out, pBlob, nBlob); - }else if( isNumber(azArg[i], 0) ){ - utf8_printf(p->out,"%s", azArg[i]); - }else if( ShellHasFlag(p, SHFLG_Newlines) ){ - output_quoted_string(p->out, azArg[i]); - }else{ - output_quoted_escaped_string(p->out, azArg[i]); - } - } - raw_printf(p->out,");\n"); - break; - } - case MODE_Quote: { - if( azArg==0 ) break; - if( p->cnt==0 && p->showHeader ){ - for(i=0; i0 ) raw_printf(p->out, ","); - output_quoted_string(p->out, azCol[i]); - } - raw_printf(p->out,"\n"); - } - p->cnt++; - for(i=0; i0 ) raw_printf(p->out, ","); - if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - utf8_printf(p->out,"NULL"); - }else if( aiType && aiType[i]==SQLITE_TEXT ){ - output_quoted_string(p->out, azArg[i]); - }else if( aiType && aiType[i]==SQLITE_INTEGER ){ - utf8_printf(p->out,"%s", azArg[i]); - }else if( aiType && aiType[i]==SQLITE_FLOAT ){ - char z[50]; - double r = sqlite3_column_double(p->pStmt, i); - sqlite3_snprintf(50,z,"%!.20g", r); - raw_printf(p->out, "%s", z); - }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ - const void *pBlob = sqlite3_column_blob(p->pStmt, i); - int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_hex_blob(p->out, pBlob, nBlob); - }else if( isNumber(azArg[i], 0) ){ - utf8_printf(p->out,"%s", azArg[i]); - }else{ - output_quoted_string(p->out, azArg[i]); - } - } - raw_printf(p->out,"\n"); - break; - } - case MODE_Ascii: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; i0 ) utf8_printf(p->out, "%s", p->colSeparator); - utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : ""); - } - utf8_printf(p->out, "%s", p->rowSeparator); - } - if( azArg==0 ) break; - for(i=0; i0 ) utf8_printf(p->out, "%s", p->colSeparator); - utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); - } - utf8_printf(p->out, "%s", p->rowSeparator); - break; - } - } - return 0; -} - -/* -** This is the callback routine that the SQLite library -** invokes for each row of a query result. -*/ -static int callback(void *pArg, int nArg, char **azArg, char **azCol){ - /* since we don't have type info, call the shell_callback with a NULL value */ - return shell_callback(pArg, nArg, azArg, azCol, NULL); -} - -/* -** This is the callback routine from sqlite3_exec() that appends all -** output onto the end of a ShellText object. -*/ -static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ - ShellText *p = (ShellText*)pArg; - int i; - UNUSED_PARAMETER(az); - if( p->n ) appendText(p, "|", 0); - for(i=0; idb, - "SAVEPOINT selftest_init;\n" - "CREATE TABLE IF NOT EXISTS selftest(\n" - " tno INTEGER PRIMARY KEY,\n" /* Test number */ - " op TEXT,\n" /* Operator: memo run */ - " cmd TEXT,\n" /* Command text */ - " ans TEXT\n" /* Desired answer */ - ");" - "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n" - "INSERT INTO [_shell$self](rowid,op,cmd)\n" - " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n" - " 'memo','Tests generated by --init');\n" - "INSERT INTO [_shell$self]\n" - " SELECT 'run',\n" - " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql " - "FROM sqlite_master ORDER BY 2'',224))',\n" - " hex(sha3_query('SELECT type,name,tbl_name,sql " - "FROM sqlite_master ORDER BY 2',224));\n" - "INSERT INTO [_shell$self]\n" - " SELECT 'run'," - " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" - " printf('%w',name) || '\" NOT INDEXED'',224))',\n" - " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n" - " FROM (\n" - " SELECT name FROM sqlite_master\n" - " WHERE type='table'\n" - " AND name<>'selftest'\n" - " AND coalesce(rootpage,0)>0\n" - " )\n" - " ORDER BY name;\n" - "INSERT INTO [_shell$self]\n" - " VALUES('run','PRAGMA integrity_check','ok');\n" - "INSERT INTO selftest(tno,op,cmd,ans)" - " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" - "DROP TABLE [_shell$self];" - ,0,0,&zErrMsg); - if( zErrMsg ){ - utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } - sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); -} - - -/* -** Set the destination table field of the ShellState structure to -** the name of the table given. Escape any quote characters in the -** table name. -*/ -static void set_table_name(ShellState *p, const char *zName){ - int i, n; - int cQuote; - char *z; - - if( p->zDestTable ){ - free(p->zDestTable); - p->zDestTable = 0; - } - if( zName==0 ) return; - cQuote = quoteChar(zName); - n = strlen30(zName); - if( cQuote ) n += n+2; - z = p->zDestTable = malloc( n+1 ); - if( z==0 ){ - raw_printf(stderr,"Error: out of memory\n"); - exit(1); - } - n = 0; - if( cQuote ) z[n++] = cQuote; - for(i=0; zName[i]; i++){ - z[n++] = zName[i]; - if( zName[i]==cQuote ) z[n++] = cQuote; - } - if( cQuote ) z[n++] = cQuote; - z[n] = 0; -} - - -/* -** Execute a query statement that will generate SQL output. Print -** the result columns, comma-separated, on a line and then add a -** semicolon terminator to the end of that line. -** -** If the number of columns is 1 and that column contains text "--" -** then write the semicolon on a separate line. That way, if a -** "--" comment occurs at the end of the statement, the comment -** won't consume the semicolon terminator. -*/ -static int run_table_dump_query( - ShellState *p, /* Query context */ - const char *zSelect, /* SELECT statement to extract content */ - const char *zFirstRow /* Print before first row, if not NULL */ -){ - sqlite3_stmt *pSelect; - int rc; - int nResult; - int i; - const char *z; - rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); - if( rc!=SQLITE_OK || !pSelect ){ - utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, - sqlite3_errmsg(p->db)); - if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; - return rc; - } - rc = sqlite3_step(pSelect); - nResult = sqlite3_column_count(pSelect); - while( rc==SQLITE_ROW ){ - if( zFirstRow ){ - utf8_printf(p->out, "%s", zFirstRow); - zFirstRow = 0; - } - z = (const char*)sqlite3_column_text(pSelect, 0); - utf8_printf(p->out, "%s", z); - for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); - } - if( z==0 ) z = ""; - while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; - if( z[0] ){ - raw_printf(p->out, "\n;\n"); - }else{ - raw_printf(p->out, ";\n"); - } - rc = sqlite3_step(pSelect); - } - rc = sqlite3_finalize(pSelect); - if( rc!=SQLITE_OK ){ - utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, - sqlite3_errmsg(p->db)); - if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; - } - return rc; -} - -/* -** Allocate space and save off current error string. -*/ -static char *save_err_msg( - sqlite3 *db /* Database to query */ -){ - int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); - char *zErrMsg = sqlite3_malloc64(nErrMsg); - if( zErrMsg ){ - memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); - } - return zErrMsg; -} - -#ifdef __linux__ -/* -** Attempt to display I/O stats on Linux using /proc/PID/io -*/ -static void displayLinuxIoStats(FILE *out){ - FILE *in; - char z[200]; - sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); - in = fopen(z, "rb"); - if( in==0 ) return; - while( fgets(z, sizeof(z), in)!=0 ){ - static const struct { - const char *zPattern; - const char *zDesc; - } aTrans[] = { - { "rchar: ", "Bytes received by read():" }, - { "wchar: ", "Bytes sent to write():" }, - { "syscr: ", "Read() system calls:" }, - { "syscw: ", "Write() system calls:" }, - { "read_bytes: ", "Bytes read from storage:" }, - { "write_bytes: ", "Bytes written to storage:" }, - { "cancelled_write_bytes: ", "Cancelled write bytes:" }, - }; - int i; - for(i=0; i1 ){ - sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); - }else{ - sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); - } - raw_printf(p->out, "%-36s %s\n", zLabel, zLine); -} - -/* -** Display memory stats. -*/ -static int display_stats( - sqlite3 *db, /* Database to query */ - ShellState *pArg, /* Pointer to ShellState */ - int bReset /* True to reset the stats */ -){ - int iCur; - int iHiwtr; - - if( pArg && pArg->out ){ - displayStatLine(pArg, "Memory Used:", - "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); - displayStatLine(pArg, "Number of Outstanding Allocations:", - "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); - if( pArg->shellFlgs & SHFLG_Pagecache ){ - displayStatLine(pArg, "Number of Pcache Pages Used:", - "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); - } - displayStatLine(pArg, "Number of Pcache Overflow Bytes:", - "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); - if( pArg->shellFlgs & SHFLG_Scratch ){ - displayStatLine(pArg, "Number of Scratch Allocations Used:", - "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); - } - displayStatLine(pArg, "Number of Scratch Overflow Bytes:", - "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); - displayStatLine(pArg, "Largest Allocation:", - "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); - displayStatLine(pArg, "Largest Pcache Allocation:", - "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); - displayStatLine(pArg, "Largest Scratch Allocation:", - "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); -#ifdef YYTRACKMAXSTACKDEPTH - displayStatLine(pArg, "Deepest Parser Stack:", - "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); -#endif - } - - if( pArg && pArg->out && db ){ - if( pArg->shellFlgs & SHFLG_Lookaside ){ - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Lookaside Slots Used: %d (max %d)\n", - iCur, iHiwtr); - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Successful lookaside attempts: %d\n", - iHiwtr); - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Lookaside failures due to size: %d\n", - iHiwtr); - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n", - iHiwtr); - } - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n", - iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache hits: %d\n", iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache misses: %d\n", iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache writes: %d\n", iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", - iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", - iCur); - } - - if( pArg && pArg->out && db && pArg->pStmt ){ - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, - bReset); - raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); - raw_printf(pArg->out, "Sort Operations: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); - raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); - raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); - } - -#ifdef __linux__ - displayLinuxIoStats(pArg->out); -#endif - - /* Do not remove this machine readable comment: extra-stats-output-here */ - - return 0; -} - -/* -** Display scan stats. -*/ -static void display_scanstats( - sqlite3 *db, /* Database to query */ - ShellState *pArg /* Pointer to ShellState */ -){ -#ifndef SQLITE_ENABLE_STMT_SCANSTATUS - UNUSED_PARAMETER(db); - UNUSED_PARAMETER(pArg); -#else - int i, k, n, mx; - raw_printf(pArg->out, "-------- scanstats --------\n"); - mx = 0; - for(k=0; k<=mx; k++){ - double rEstLoop = 1.0; - for(i=n=0; 1; i++){ - sqlite3_stmt *p = pArg->pStmt; - sqlite3_int64 nLoop, nVisit; - double rEst; - int iSid; - const char *zExplain; - if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){ - break; - } - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid); - if( iSid>mx ) mx = iSid; - if( iSid!=k ) continue; - if( n==0 ){ - rEstLoop = (double)nLoop; - if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k); - } - n++; - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit); - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst); - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); - utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain); - rEstLoop *= rEst; - raw_printf(pArg->out, - " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n", - nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst - ); - } - } - raw_printf(pArg->out, "---------------------------\n"); -#endif -} - -/* -** Parameter azArray points to a zero-terminated array of strings. zStr -** points to a single nul-terminated string. Return non-zero if zStr -** is equal, according to strcmp(), to any of the strings in the array. -** Otherwise, return zero. -*/ -static int str_in_array(const char *zStr, const char **azArray){ - int i; - for(i=0; azArray[i]; i++){ - if( 0==strcmp(zStr, azArray[i]) ) return 1; - } - return 0; -} - -/* -** If compiled statement pSql appears to be an EXPLAIN statement, allocate -** and populate the ShellState.aiIndent[] array with the number of -** spaces each opcode should be indented before it is output. -** -** The indenting rules are: -** -** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent -** all opcodes that occur between the p2 jump destination and the opcode -** itself by 2 spaces. -** -** * For each "Goto", if the jump destination is earlier in the program -** and ends on one of: -** Yield SeekGt SeekLt RowSetRead Rewind -** or if the P1 parameter is one instead of zero, -** then indent all opcodes between the earlier instruction -** and "Goto" by 2 spaces. -*/ -static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ - const char *zSql; /* The text of the SQL statement */ - const char *z; /* Used to check if this is an EXPLAIN */ - int *abYield = 0; /* True if op is an OP_Yield */ - int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ - int iOp; /* Index of operation in p->aiIndent[] */ - - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", - "NextIfOpen", "PrevIfOpen", 0 }; - const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", - "Rewind", 0 }; - const char *azGoto[] = { "Goto", 0 }; - - /* Try to figure out if this is really an EXPLAIN statement. If this - ** cannot be verified, return early. */ - if( sqlite3_column_count(pSql)!=8 ){ - p->cMode = p->mode; - return; - } - zSql = sqlite3_sql(pSql); - if( zSql==0 ) return; - for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++); - if( sqlite3_strnicmp(z, "explain", 7) ){ - p->cMode = p->mode; - return; - } - - for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ - int i; - int iAddr = sqlite3_column_int(pSql, 0); - const char *zOp = (const char*)sqlite3_column_text(pSql, 1); - - /* Set p2 to the P2 field of the current opcode. Then, assuming that - ** p2 is an instruction address, set variable p2op to the index of that - ** instruction in the aiIndent[] array. p2 and p2op may be different if - ** the current instruction is part of a sub-program generated by an - ** SQL trigger or foreign key. */ - int p2 = sqlite3_column_int(pSql, 3); - int p2op = (p2 + (iOp-iAddr)); - - /* Grow the p->aiIndent array as required */ - if( iOp>=nAlloc ){ - if( iOp==0 ){ - /* Do further verfication that this is explain output. Abort if - ** it is not */ - static const char *explainCols[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" }; - int jj; - for(jj=0; jjcMode = p->mode; - sqlite3_reset(pSql); - return; - } - } - } - nAlloc += 100; - p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); - abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); - } - abYield[iOp] = str_in_array(zOp, azYield); - p->aiIndent[iOp] = 0; - p->nIndent = iOp+1; - - if( str_in_array(zOp, azNext) ){ - for(i=p2op; iaiIndent[i] += 2; - } - if( str_in_array(zOp, azGoto) && p2opnIndent - && (abYield[p2op] || sqlite3_column_int(pSql, 2)) - ){ - for(i=p2op; iaiIndent[i] += 2; - } - } - - p->iIndent = 0; - sqlite3_free(abYield); - sqlite3_reset(pSql); -} - -/* -** Free the array allocated by explain_data_prepare(). -*/ -static void explain_data_delete(ShellState *p){ - sqlite3_free(p->aiIndent); - p->aiIndent = 0; - p->nIndent = 0; - p->iIndent = 0; -} - -/* -** Disable and restore .wheretrace and .selecttrace settings. -*/ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) -extern int sqlite3SelectTrace; -static int savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) -extern int sqlite3WhereTrace; -static int savedWhereTrace; -#endif -static void disable_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - savedSelectTrace = sqlite3SelectTrace; - sqlite3SelectTrace = 0; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - savedWhereTrace = sqlite3WhereTrace; - sqlite3WhereTrace = 0; -#endif -} -static void restore_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - sqlite3SelectTrace = savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - sqlite3WhereTrace = savedWhereTrace; -#endif -} - -/* -** Run a prepared statement -*/ -static void exec_prepared_stmt( - ShellState *pArg, /* Pointer to ShellState */ - sqlite3_stmt *pStmt, /* Statment to run */ - int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */ -){ - int rc; - - /* perform the first step. this will tell us if we - ** have a result set or not and how wide it is. - */ - rc = sqlite3_step(pStmt); - /* if we have a result set... */ - if( SQLITE_ROW == rc ){ - /* if we have a callback... */ - if( xCallback ){ - /* allocate space for col name ptr, value ptr, and type */ - int nCol = sqlite3_column_count(pStmt); - void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); - if( !pData ){ - rc = SQLITE_NOMEM; - }else{ - char **azCols = (char **)pData; /* Names of result columns */ - char **azVals = &azCols[nCol]; /* Results */ - int *aiTypes = (int *)&azVals[nCol]; /* Result types */ - int i, x; - assert(sizeof(int) <= sizeof(char *)); - /* save off ptrs to column names */ - for(i=0; icMode==MODE_Insert ){ - azVals[i] = ""; - }else{ - azVals[i] = (char*)sqlite3_column_text(pStmt, i); - } - if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ - rc = SQLITE_NOMEM; - break; /* from for */ - } - } /* end for */ - - /* if data and types extracted successfully... */ - if( SQLITE_ROW == rc ){ - /* call the supplied callback with the result row data */ - if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ - rc = SQLITE_ABORT; - }else{ - rc = sqlite3_step(pStmt); - } - } - } while( SQLITE_ROW == rc ); - sqlite3_free(pData); - } - }else{ - do{ - rc = sqlite3_step(pStmt); - } while( rc == SQLITE_ROW ); - } - } -} - -/* -** Execute a statement or set of statements. Print -** any result rows/columns depending on the current mode -** set via the supplied callback. -** -** This is very similar to SQLite's built-in sqlite3_exec() -** function except it takes a slightly different callback -** and callback data argument. -*/ -static int shell_exec( - sqlite3 *db, /* An open database */ - const char *zSql, /* SQL to be evaluated */ - int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ - /* (not the same as sqlite3_exec) */ - ShellState *pArg, /* Pointer to ShellState */ - char **pzErrMsg /* Error msg written here */ -){ - sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ - int rc = SQLITE_OK; /* Return Code */ - int rc2; - const char *zLeftover; /* Tail of unprocessed SQL */ - - if( pzErrMsg ){ - *pzErrMsg = NULL; - } - - while( zSql[0] && (SQLITE_OK == rc) ){ - static const char *zStmtSql; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); - if( SQLITE_OK != rc ){ - if( pzErrMsg ){ - *pzErrMsg = save_err_msg(db); - } - }else{ - if( !pStmt ){ - /* this happens for a comment or white-space */ - zSql = zLeftover; - while( IsSpace(zSql[0]) ) zSql++; - continue; - } - zStmtSql = sqlite3_sql(pStmt); - if( zStmtSql==0 ) zStmtSql = ""; - while( IsSpace(zStmtSql[0]) ) zStmtSql++; - - /* save off the prepared statment handle and reset row count */ - if( pArg ){ - pArg->pStmt = pStmt; - pArg->cnt = 0; - } - - /* echo the sql statement if echo on */ - if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){ - utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); - } - - /* Show the EXPLAIN QUERY PLAN if .eqp is on */ - if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){ - sqlite3_stmt *pExplain; - char *zEQP; - disable_debug_trace_modes(); - zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); - if( rc==SQLITE_OK ){ - while( sqlite3_step(pExplain)==SQLITE_ROW ){ - raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0)); - raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); - raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); - utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); - } - } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); - if( pArg->autoEQP>=2 ){ - /* Also do an EXPLAIN for ".eqp full" mode */ - zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); - if( rc==SQLITE_OK ){ - pArg->cMode = MODE_Explain; - explain_data_prepare(pArg, pExplain); - exec_prepared_stmt(pArg, pExplain, xCallback); - explain_data_delete(pArg); - } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); - } - restore_debug_trace_modes(); - } - - if( pArg ){ - pArg->cMode = pArg->mode; - if( pArg->autoExplain - && sqlite3_column_count(pStmt)==8 - && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 - ){ - pArg->cMode = MODE_Explain; - } - - /* If the shell is currently in ".explain" mode, gather the extra - ** data required to add indents to the output.*/ - if( pArg->cMode==MODE_Explain ){ - explain_data_prepare(pArg, pStmt); - } - } - - exec_prepared_stmt(pArg, pStmt, xCallback); - explain_data_delete(pArg); - - /* print usage stats if stats on */ - if( pArg && pArg->statsOn ){ - display_stats(db, pArg, 0); - } - - /* print loop-counters if required */ - if( pArg && pArg->scanstatsOn ){ - display_scanstats(db, pArg); - } - - /* Finalize the statement just executed. If this fails, save a - ** copy of the error message. Otherwise, set zSql to point to the - ** next statement to execute. */ - rc2 = sqlite3_finalize(pStmt); - if( rc!=SQLITE_NOMEM ) rc = rc2; - if( rc==SQLITE_OK ){ - zSql = zLeftover; - while( IsSpace(zSql[0]) ) zSql++; - }else if( pzErrMsg ){ - *pzErrMsg = save_err_msg(db); - } - - /* clear saved stmt handle */ - if( pArg ){ - pArg->pStmt = NULL; - } - } - } /* end while */ - - return rc; -} - -/* -** Release memory previously allocated by tableColumnList(). -*/ -static void freeColumnList(char **azCol){ - int i; - for(i=1; azCol[i]; i++){ - sqlite3_free(azCol[i]); - } - /* azCol[0] is a static string */ - sqlite3_free(azCol); -} - -/* -** Return a list of pointers to strings which are the names of all -** columns in table zTab. The memory to hold the names is dynamically -** allocated and must be released by the caller using a subsequent call -** to freeColumnList(). -** -** The azCol[0] entry is usually NULL. However, if zTab contains a rowid -** value that needs to be preserved, then azCol[0] is filled in with the -** name of the rowid column. -** -** The first regular column in the table is azCol[1]. The list is terminated -** by an entry with azCol[i]==0. -*/ -static char **tableColumnList(ShellState *p, const char *zTab){ - char **azCol = 0; - sqlite3_stmt *pStmt; - char *zSql; - int nCol = 0; - int nAlloc = 0; - int nPK = 0; /* Number of PRIMARY KEY columns seen */ - int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ - int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); - int rc; - - zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - if( rc ) return 0; - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - if( nCol>=nAlloc-2 ){ - nAlloc = nAlloc*2 + nCol + 10; - azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); - if( azCol==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - exit(1); - } - } - azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); - if( sqlite3_column_int(pStmt, 5) ){ - nPK++; - if( nPK==1 - && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2), - "INTEGER")==0 - ){ - isIPK = 1; - }else{ - isIPK = 0; - } - } - } - sqlite3_finalize(pStmt); - azCol[0] = 0; - azCol[nCol+1] = 0; - - /* The decision of whether or not a rowid really needs to be preserved - ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table - ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve - ** rowids on tables where the rowid is inaccessible because there are other - ** columns in the table named "rowid", "_rowid_", and "oid". - */ - if( preserveRowid && isIPK ){ - /* If a single PRIMARY KEY column with type INTEGER was seen, then it - ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID - ** table or a INTEGER PRIMARY KEY DESC column, neither of which are - ** ROWID aliases. To distinguish these cases, check to see if - ** there is a "pk" entry in "PRAGMA index_list". There will be - ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. - */ - zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" - " WHERE origin='pk'", zTab); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - if( rc ){ - freeColumnList(azCol); - return 0; - } - rc = sqlite3_step(pStmt); - sqlite3_finalize(pStmt); - preserveRowid = rc==SQLITE_ROW; - } - if( preserveRowid ){ - /* Only preserve the rowid if we can find a name to use for the - ** rowid */ - static char *azRowid[] = { "rowid", "_rowid_", "oid" }; - int i, j; - for(j=0; j<3; j++){ - for(i=1; i<=nCol; i++){ - if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break; - } - if( i>nCol ){ - /* At this point, we know that azRowid[j] is not the name of any - ** ordinary column in the table. Verify that azRowid[j] is a valid - ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID - ** tables will fail this last check */ - rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); - if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; - break; - } - } - } - return azCol; -} - -/* -** Toggle the reverse_unordered_selects setting. -*/ -static void toggleSelectOrder(sqlite3 *db){ - sqlite3_stmt *pStmt = 0; - int iSetting = 0; - char zStmt[100]; - sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0); - if( sqlite3_step(pStmt)==SQLITE_ROW ){ - iSetting = sqlite3_column_int(pStmt, 0); - } - sqlite3_finalize(pStmt); - sqlite3_snprintf(sizeof(zStmt), zStmt, - "PRAGMA reverse_unordered_selects(%d)", !iSetting); - sqlite3_exec(db, zStmt, 0, 0, 0); -} - -/* -** This is a different callback routine used for dumping the database. -** Each row received by this callback consists of a table name, -** the table type ("index" or "table") and SQL to create the table. -** This routine should print text sufficient to recreate the table. -*/ -static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ - int rc; - const char *zTable; - const char *zType; - const char *zSql; - ShellState *p = (ShellState *)pArg; - - UNUSED_PARAMETER(azNotUsed); - if( nArg!=3 ) return 1; - zTable = azArg[0]; - zType = azArg[1]; - zSql = azArg[2]; - - if( strcmp(zTable, "sqlite_sequence")==0 ){ - raw_printf(p->out, "DELETE FROM sqlite_sequence;\n"); - }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ - raw_printf(p->out, "ANALYZE sqlite_master;\n"); - }else if( strncmp(zTable, "sqlite_", 7)==0 ){ - return 0; - }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ - char *zIns; - if( !p->writableSchema ){ - raw_printf(p->out, "PRAGMA writable_schema=ON;\n"); - p->writableSchema = 1; - } - zIns = sqlite3_mprintf( - "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" - "VALUES('table','%q','%q',0,'%q');", - zTable, zTable, zSql); - utf8_printf(p->out, "%s\n", zIns); - sqlite3_free(zIns); - return 0; - }else{ - printSchemaLine(p->out, zSql, ";\n"); - } - - if( strcmp(zType, "table")==0 ){ - ShellText sSelect; - ShellText sTable; - char **azCol; - int i; - char *savedDestTable; - int savedMode; - - azCol = tableColumnList(p, zTable); - if( azCol==0 ){ - p->nErr++; - return 0; - } - - /* Always quote the table name, even if it appears to be pure ascii, - ** in case it is a keyword. Ex: INSERT INTO "table" ... */ - initText(&sTable); - appendText(&sTable, zTable, quoteChar(zTable)); - /* If preserving the rowid, add a column list after the table name. - ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" - ** instead of the usual "INSERT INTO tab VALUES(...)". - */ - if( azCol[0] ){ - appendText(&sTable, "(", 0); - appendText(&sTable, azCol[0], 0); - for(i=1; azCol[i]; i++){ - appendText(&sTable, ",", 0); - appendText(&sTable, azCol[i], quoteChar(azCol[i])); - } - appendText(&sTable, ")", 0); - } - - /* Build an appropriate SELECT statement */ - initText(&sSelect); - appendText(&sSelect, "SELECT ", 0); - if( azCol[0] ){ - appendText(&sSelect, azCol[0], 0); - appendText(&sSelect, ",", 0); - } - for(i=1; azCol[i]; i++){ - appendText(&sSelect, azCol[i], quoteChar(azCol[i])); - if( azCol[i+1] ){ - appendText(&sSelect, ",", 0); - } - } - freeColumnList(azCol); - appendText(&sSelect, " FROM ", 0); - appendText(&sSelect, zTable, quoteChar(zTable)); - - savedDestTable = p->zDestTable; - savedMode = p->mode; - p->zDestTable = sTable.z; - p->mode = p->cMode = MODE_Insert; - rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); - if( (rc&0xff)==SQLITE_CORRUPT ){ - raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); - toggleSelectOrder(p->db); - shell_exec(p->db, sSelect.z, shell_callback, p, 0); - toggleSelectOrder(p->db); - } - p->zDestTable = savedDestTable; - p->mode = savedMode; - freeText(&sTable); - freeText(&sSelect); - if( rc ) p->nErr++; - } - return 0; -} - -/* -** Run zQuery. Use dump_callback() as the callback routine so that -** the contents of the query are output as SQL statements. -** -** If we get a SQLITE_CORRUPT error, rerun the query after appending -** "ORDER BY rowid DESC" to the end. -*/ -static int run_schema_dump_query( - ShellState *p, - const char *zQuery -){ - int rc; - char *zErr = 0; - rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); - if( rc==SQLITE_CORRUPT ){ - char *zQ2; - int len = strlen30(zQuery); - raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); - if( zErr ){ - utf8_printf(p->out, "/****** %s ******/\n", zErr); - sqlite3_free(zErr); - zErr = 0; - } - zQ2 = malloc( len+100 ); - if( zQ2==0 ) return rc; - sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); - rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); - if( rc ){ - utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr); - }else{ - rc = SQLITE_CORRUPT; - } - sqlite3_free(zErr); - free(zQ2); - } - return rc; -} - -/* -** Text of a help message -*/ -static char zHelp[] = -#ifndef SQLITE_OMIT_AUTHORIZATION - ".auth ON|OFF Show authorizer callbacks\n" -#endif - ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" - ".bail on|off Stop after hitting an error. Default OFF\n" - ".binary on|off Turn binary output on or off. Default OFF\n" - ".cd DIRECTORY Change the working directory to DIRECTORY\n" - ".changes on|off Show number of rows changed by SQL\n" - ".check GLOB Fail if output since .testcase does not match\n" - ".clone NEWDB Clone data into NEWDB from the existing database\n" - ".databases List names and files of attached databases\n" - ".dbinfo ?DB? Show status information about the database\n" - ".dump ?TABLE? ... Dump the database in an SQL text format\n" - " If TABLE specified, only dump tables matching\n" - " LIKE pattern TABLE.\n" - ".echo on|off Turn command echo on or off\n" - ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" - ".exit Exit this program\n" -/* Because explain mode comes on automatically now, the ".explain" mode -** is removed from the help screen. It is still supported for legacy, however */ -/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/ - ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" - ".headers on|off Turn display of headers on or off\n" - ".help Show this message\n" - ".import FILE TABLE Import data from FILE into TABLE\n" -#ifndef SQLITE_OMIT_TEST_CONTROL - ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n" -#endif - ".indexes ?TABLE? Show names of all indexes\n" - " If TABLE specified, only show indexes for tables\n" - " matching LIKE pattern TABLE.\n" -#ifdef SQLITE_ENABLE_IOTRACE - ".iotrace FILE Enable I/O diagnostic logging to FILE\n" -#endif - ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" - ".lint OPTIONS Report potential schema issues. Options:\n" - " fkey-indexes Find missing foreign key indexes\n" -#ifndef SQLITE_OMIT_LOAD_EXTENSION - ".load FILE ?ENTRY? Load an extension library\n" -#endif - ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" - ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" - " ascii Columns/rows delimited by 0x1F and 0x1E\n" - " csv Comma-separated values\n" - " column Left-aligned columns. (See .width)\n" - " html HTML code\n" - " insert SQL insert statements for TABLE\n" - " line One value per line\n" - " list Values delimited by \"|\"\n" - " quote Escape answers as for SQL\n" - " tabs Tab-separated values\n" - " tcl TCL list elements\n" - ".nullvalue STRING Use STRING in place of NULL values\n" - ".once FILENAME Output for the next SQL command only to FILENAME\n" - ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n" - " The --new option starts with an empty file\n" - ".output ?FILENAME? Send output to FILENAME or stdout\n" - ".print STRING... Print literal STRING\n" - ".prompt MAIN CONTINUE Replace the standard prompts\n" - ".quit Exit this program\n" - ".read FILENAME Execute SQL in FILENAME\n" - ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" - ".save FILE Write in-memory database into FILE\n" - ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" - ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" - " Add --indent for pretty-printing\n" - ".selftest ?--init? Run tests defined in the SELFTEST table\n" - ".separator COL ?ROW? Change the column separator and optionally the row\n" - " separator for both the output mode and .import\n" -#if defined(SQLITE_ENABLE_SESSION) - ".session CMD ... Create or control sessions\n" -#endif - ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n" - ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" - ".show Show the current values for various settings\n" - ".stats ?on|off? Show stats or turn stats on or off\n" - ".system CMD ARGS... Run CMD ARGS... in a system shell\n" - ".tables ?TABLE? List names of tables\n" - " If TABLE specified, only list tables matching\n" - " LIKE pattern TABLE.\n" - ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" - ".timeout MS Try opening locked tables for MS milliseconds\n" - ".timer on|off Turn SQL timer on or off\n" - ".trace FILE|off Output each SQL statement as it is run\n" - ".vfsinfo ?AUX? Information about the top-level VFS\n" - ".vfslist List all available VFSes\n" - ".vfsname ?AUX? Print the name of the VFS stack\n" - ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" - " Negative values right-justify\n" -; - -#if defined(SQLITE_ENABLE_SESSION) -/* -** Print help information for the ".sessions" command -*/ -void session_help(ShellState *p){ - raw_printf(p->out, - ".session ?NAME? SUBCOMMAND ?ARGS...?\n" - "If ?NAME? is omitted, the first defined session is used.\n" - "Subcommands:\n" - " attach TABLE Attach TABLE\n" - " changeset FILE Write a changeset into FILE\n" - " close Close one session\n" - " enable ?BOOLEAN? Set or query the enable bit\n" - " filter GLOB... Reject tables matching GLOBs\n" - " indirect ?BOOLEAN? Mark or query the indirect status\n" - " isempty Query whether the session is empty\n" - " list List currently open session names\n" - " open DB NAME Open a new session on DB\n" - " patchset FILE Write a patchset into FILE\n" - ); -} -#endif - - -/* Forward reference */ -static int process_input(ShellState *p, FILE *in); - -/* -** Read the content of file zName into memory obtained from sqlite3_malloc64() -** and return a pointer to the buffer. The caller is responsible for freeing -** the memory. -** -** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes -** read. -** -** For convenience, a nul-terminator byte is always appended to the data read -** from the file before the buffer is returned. This byte is not included in -** the final value of (*pnByte), if applicable. -** -** NULL is returned if any error is encountered. The final value of *pnByte -** is undefined in this case. -*/ -static char *readFile(const char *zName, int *pnByte){ - FILE *in = fopen(zName, "rb"); - long nIn; - size_t nRead; - char *pBuf; - if( in==0 ) return 0; - fseek(in, 0, SEEK_END); - nIn = ftell(in); - rewind(in); - pBuf = sqlite3_malloc64( nIn+1 ); - if( pBuf==0 ) return 0; - nRead = fread(pBuf, nIn, 1, in); - fclose(in); - if( nRead!=1 ){ - sqlite3_free(pBuf); - return 0; - } - pBuf[nIn] = 0; - if( pnByte ) *pnByte = nIn; - return pBuf; -} - -#if defined(SQLITE_ENABLE_SESSION) -/* -** Close a single OpenSession object and release all of its associated -** resources. -*/ -static void session_close(OpenSession *pSession){ - int i; - sqlite3session_delete(pSession->p); - sqlite3_free(pSession->zName); - for(i=0; inFilter; i++){ - sqlite3_free(pSession->azFilter[i]); - } - sqlite3_free(pSession->azFilter); - memset(pSession, 0, sizeof(OpenSession)); -} -#endif - -/* -** Close all OpenSession objects and release all associated resources. -*/ -#if defined(SQLITE_ENABLE_SESSION) -static void session_close_all(ShellState *p){ - int i; - for(i=0; inSession; i++){ - session_close(&p->aSession[i]); - } - p->nSession = 0; -} -#else -# define session_close_all(X) -#endif - -/* -** Implementation of the xFilter function for an open session. Omit -** any tables named by ".session filter" but let all other table through. -*/ -#if defined(SQLITE_ENABLE_SESSION) -static int session_filter(void *pCtx, const char *zTab){ - OpenSession *pSession = (OpenSession*)pCtx; - int i; - for(i=0; inFilter; i++){ - if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0; - } - return 1; -} -#endif - -/* -** Make sure the database is open. If it is not, then open it. If -** the database fails to open, print an error message and exit. -*/ -static void open_db(ShellState *p, int keepAlive){ - if( p->db==0 ){ - sqlite3_initialize(); - sqlite3_open(p->zDbFilename, &p->db); - globalDb = p->db; - if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", - p->zDbFilename, sqlite3_errmsg(p->db)); - if( keepAlive ) return; - exit(1); - } -#ifndef SQLITE_OMIT_LOAD_EXTENSION - sqlite3_enable_load_extension(p->db, 1); -#endif - sqlite3_fileio_init(p->db, 0, 0); - sqlite3_shathree_init(p->db, 0, 0); - sqlite3_completion_init(p->db, 0, 0); - sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0, - shellAddSchemaName, 0, 0); - } -} - -#if HAVE_READLINE || HAVE_EDITLINE -/* -** Readline completion callbacks -*/ -static char *readline_completion_generator(const char *text, int state){ - static sqlite3_stmt *pStmt = 0; - char *zRet; - if( state==0 ){ - char *zSql; - sqlite3_finalize(pStmt); - zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" - " FROM completion(%Q) ORDER BY 1", text); - sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - } - if( sqlite3_step(pStmt)==SQLITE_ROW ){ - zRet = strdup((const char*)sqlite3_column_text(pStmt, 0)); - }else{ - sqlite3_finalize(pStmt); - pStmt = 0; - zRet = 0; - } - return zRet; -} -static char **readline_completion(const char *zText, int iStart, int iEnd){ - rl_attempted_completion_over = 1; - return rl_completion_matches(zText, readline_completion_generator); -} - -#elif HAVE_LINENOISE -/* -** Linenoise completion callback -*/ -static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){ - int nLine = (int)strlen(zLine); - int i, iStart; - sqlite3_stmt *pStmt = 0; - char *zSql; - char zBuf[1000]; - - if( nLine>sizeof(zBuf)-30 ) return; - if( zLine[0]=='.' ) return; - for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){} - if( i==nLine-1 ) return; - iStart = i+1; - memcpy(zBuf, zLine, iStart); - zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" - " FROM completion(%Q,%Q) ORDER BY 1", - &zLine[iStart], zLine); - sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */ - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0); - int nCompletion = sqlite3_column_bytes(pStmt, 0); - if( iStart+nCompletion < sizeof(zBuf)-1 ){ - memcpy(zBuf+iStart, zCompletion, nCompletion+1); - linenoiseAddCompletion(lc, zBuf); - } - } - sqlite3_finalize(pStmt); -} -#endif - -/* -** Do C-language style dequoting. -** -** \a -> alarm -** \b -> backspace -** \t -> tab -** \n -> newline -** \v -> vertical tab -** \f -> form feed -** \r -> carriage return -** \s -> space -** \" -> " -** \' -> ' -** \\ -> backslash -** \NNN -> ascii character NNN in octal -*/ -static void resolve_backslashes(char *z){ - int i, j; - char c; - while( *z && *z!='\\' ) z++; - for(i=j=0; (c = z[i])!=0; i++, j++){ - if( c=='\\' && z[i+1]!=0 ){ - c = z[++i]; - if( c=='a' ){ - c = '\a'; - }else if( c=='b' ){ - c = '\b'; - }else if( c=='t' ){ - c = '\t'; - }else if( c=='n' ){ - c = '\n'; - }else if( c=='v' ){ - c = '\v'; - }else if( c=='f' ){ - c = '\f'; - }else if( c=='r' ){ - c = '\r'; - }else if( c=='"' ){ - c = '"'; - }else if( c=='\'' ){ - c = '\''; - }else if( c=='\\' ){ - c = '\\'; - }else if( c>='0' && c<='7' ){ - c -= '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - } - } - } - } - z[j] = c; - } - if( j='0' && c<='9' ) return c - '0'; - if( c>='a' && c<='f' ) return c - 'a' + 10; - if( c>='A' && c<='F' ) return c - 'A' + 10; - return -1; -} - -/* -** Interpret zArg as an integer value, possibly with suffixes. -*/ -static sqlite3_int64 integerValue(const char *zArg){ - sqlite3_int64 v = 0; - static const struct { char *zSuffix; int iMult; } aMult[] = { - { "KiB", 1024 }, - { "MiB", 1024*1024 }, - { "GiB", 1024*1024*1024 }, - { "KB", 1000 }, - { "MB", 1000000 }, - { "GB", 1000000000 }, - { "K", 1000 }, - { "M", 1000000 }, - { "G", 1000000000 }, - }; - int i; - int isNeg = 0; - if( zArg[0]=='-' ){ - isNeg = 1; - zArg++; - }else if( zArg[0]=='+' ){ - zArg++; - } - if( zArg[0]=='0' && zArg[1]=='x' ){ - int x; - zArg += 2; - while( (x = hexDigitValue(zArg[0]))>=0 ){ - v = (v<<4) + x; - zArg++; - } - }else{ - while( IsDigit(zArg[0]) ){ - v = v*10 + zArg[0] - '0'; - zArg++; - } - } - for(i=0; i=0; i++){} - }else{ - for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} - } - if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff); - if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ - return 1; - } - if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ - return 0; - } - utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", - zArg); - return 0; -} - -/* -** Set or clear a shell flag according to a boolean value. -*/ -static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){ - if( booleanValue(zArg) ){ - ShellSetFlag(p, mFlag); - }else{ - ShellClearFlag(p, mFlag); - } -} - -/* -** Close an output file, assuming it is not stderr or stdout -*/ -static void output_file_close(FILE *f){ - if( f && f!=stdout && f!=stderr ) fclose(f); -} - -/* -** Try to open an output file. The names "stdout" and "stderr" are -** recognized and do the right thing. NULL is returned if the output -** filename is "off". -*/ -static FILE *output_file_open(const char *zFile){ - FILE *f; - if( strcmp(zFile,"stdout")==0 ){ - f = stdout; - }else if( strcmp(zFile, "stderr")==0 ){ - f = stderr; - }else if( strcmp(zFile, "off")==0 ){ - f = 0; - }else{ - f = fopen(zFile, "wb"); - if( f==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); - } - } - return f; -} - -#if !defined(SQLITE_UNTESTABLE) -#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) -/* -** A routine for handling output from sqlite3_trace(). -*/ -static int sql_trace_callback( - unsigned mType, - void *pArg, - void *pP, - void *pX -){ - FILE *f = (FILE*)pArg; - UNUSED_PARAMETER(mType); - UNUSED_PARAMETER(pP); - if( f ){ - const char *z = (const char*)pX; - int i = (int)strlen(z); - while( i>0 && z[i-1]==';' ){ i--; } - utf8_printf(f, "%.*s;\n", i, z); - } - return 0; -} -#endif -#endif - -/* -** A no-op routine that runs with the ".breakpoint" doc-command. This is -** a useful spot to set a debugger breakpoint. -*/ -static void test_breakpoint(void){ - static int nCall = 0; - nCall++; -} - -/* -** An object used to read a CSV and other files for import. -*/ -typedef struct ImportCtx ImportCtx; -struct ImportCtx { - const char *zFile; /* Name of the input file */ - FILE *in; /* Read the CSV text from this input stream */ - char *z; /* Accumulated text for a field */ - int n; /* Number of bytes in z */ - int nAlloc; /* Space allocated for z[] */ - int nLine; /* Current line number */ - int bNotFirst; /* True if one or more bytes already read */ - int cTerm; /* Character that terminated the most recent field */ - int cColSep; /* The column separator character. (Usually ",") */ - int cRowSep; /* The row separator character. (Usually "\n") */ -}; - -/* Append a single byte to z[] */ -static void import_append_char(ImportCtx *p, int c){ - if( p->n+1>=p->nAlloc ){ - p->nAlloc += p->nAlloc + 100; - p->z = sqlite3_realloc64(p->z, p->nAlloc); - if( p->z==0 ){ - raw_printf(stderr, "out of memory\n"); - exit(1); - } - } - p->z[p->n++] = (char)c; -} - -/* Read a single field of CSV text. Compatible with rfc4180 and extended -** with the option of having a separator other than ",". -** -** + Input comes from p->in. -** + Store results in p->z of length p->n. Space to hold p->z comes -** from sqlite3_malloc64(). -** + Use p->cSep as the column separator. The default is ",". -** + Use p->rSep as the row separator. The default is "\n". -** + Keep track of the line number in p->nLine. -** + Store the character that terminates the field in p->cTerm. Store -** EOF on end-of-file. -** + Report syntax errors on stderr -*/ -static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ - int c; - int cSep = p->cColSep; - int rSep = p->cRowSep; - p->n = 0; - c = fgetc(p->in); - if( c==EOF || seenInterrupt ){ - p->cTerm = EOF; - return 0; - } - if( c=='"' ){ - int pc, ppc; - int startLine = p->nLine; - int cQuote = c; - pc = ppc = 0; - while( 1 ){ - c = fgetc(p->in); - if( c==rSep ) p->nLine++; - if( c==cQuote ){ - if( pc==cQuote ){ - pc = 0; - continue; - } - } - if( (c==cSep && pc==cQuote) - || (c==rSep && pc==cQuote) - || (c==rSep && pc=='\r' && ppc==cQuote) - || (c==EOF && pc==cQuote) - ){ - do{ p->n--; }while( p->z[p->n]!=cQuote ); - p->cTerm = c; - break; - } - if( pc==cQuote && c!='\r' ){ - utf8_printf(stderr, "%s:%d: unescaped %c character\n", - p->zFile, p->nLine, cQuote); - } - if( c==EOF ){ - utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n", - p->zFile, startLine, cQuote); - p->cTerm = c; - break; - } - import_append_char(p, c); - ppc = pc; - pc = c; - } - }else{ - /* If this is the first field being parsed and it begins with the - ** UTF-8 BOM (0xEF BB BF) then skip the BOM */ - if( (c&0xff)==0xef && p->bNotFirst==0 ){ - import_append_char(p, c); - c = fgetc(p->in); - if( (c&0xff)==0xbb ){ - import_append_char(p, c); - c = fgetc(p->in); - if( (c&0xff)==0xbf ){ - p->bNotFirst = 1; - p->n = 0; - return csv_read_one_field(p); - } - } - } - while( c!=EOF && c!=cSep && c!=rSep ){ - import_append_char(p, c); - c = fgetc(p->in); - } - if( c==rSep ){ - p->nLine++; - if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; - } - p->cTerm = c; - } - if( p->z ) p->z[p->n] = 0; - p->bNotFirst = 1; - return p->z; -} - -/* Read a single field of ASCII delimited text. -** -** + Input comes from p->in. -** + Store results in p->z of length p->n. Space to hold p->z comes -** from sqlite3_malloc64(). -** + Use p->cSep as the column separator. The default is "\x1F". -** + Use p->rSep as the row separator. The default is "\x1E". -** + Keep track of the row number in p->nLine. -** + Store the character that terminates the field in p->cTerm. Store -** EOF on end-of-file. -** + Report syntax errors on stderr -*/ -static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){ - int c; - int cSep = p->cColSep; - int rSep = p->cRowSep; - p->n = 0; - c = fgetc(p->in); - if( c==EOF || seenInterrupt ){ - p->cTerm = EOF; - return 0; - } - while( c!=EOF && c!=cSep && c!=rSep ){ - import_append_char(p, c); - c = fgetc(p->in); - } - if( c==rSep ){ - p->nLine++; - } - p->cTerm = c; - if( p->z ) p->z[p->n] = 0; - return p->z; -} - -/* -** Try to transfer data for table zTable. If an error is seen while -** moving forward, try to go backwards. The backwards movement won't -** work for WITHOUT ROWID tables. -*/ -static void tryToCloneData( - ShellState *p, - sqlite3 *newDb, - const char *zTable -){ - sqlite3_stmt *pQuery = 0; - sqlite3_stmt *pInsert = 0; - char *zQuery = 0; - char *zInsert = 0; - int rc; - int i, j, n; - int nTable = (int)strlen(zTable); - int k = 0; - int cnt = 0; - const int spinRate = 10000; - - zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); - rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Error %d: %s on [%s]\n", - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), - zQuery); - goto end_data_xfer; - } - n = sqlite3_column_count(pQuery); - zInsert = sqlite3_malloc64(200 + nTable + n*3); - if( zInsert==0 ){ - raw_printf(stderr, "out of memory\n"); - goto end_data_xfer; - } - sqlite3_snprintf(200+nTable,zInsert, - "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); - i = (int)strlen(zInsert); - for(j=1; jdb, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable); - break; - } - } /* End for(k=0...) */ - -end_data_xfer: - sqlite3_finalize(pQuery); - sqlite3_finalize(pInsert); - sqlite3_free(zQuery); - sqlite3_free(zInsert); -} - - -/* -** Try to transfer all rows of the schema that match zWhere. For -** each row, invoke xForEach() on the object defined by that row. -** If an error is encountered while moving forward through the -** sqlite_master table, try again moving backwards. -*/ -static void tryToCloneSchema( - ShellState *p, - sqlite3 *newDb, - const char *zWhere, - void (*xForEach)(ShellState*,sqlite3*,const char*) -){ - sqlite3_stmt *pQuery = 0; - char *zQuery = 0; - int rc; - const unsigned char *zName; - const unsigned char *zSql; - char *zErrMsg = 0; - - zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" - " WHERE %s", zWhere); - rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Error: (%d) %s on [%s]\n", - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), - zQuery); - goto end_schema_xfer; - } - while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ - zName = sqlite3_column_text(pQuery, 0); - zSql = sqlite3_column_text(pQuery, 1); - printf("%s... ", zName); fflush(stdout); - sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); - if( zErrMsg ){ - utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); - sqlite3_free(zErrMsg); - zErrMsg = 0; - } - if( xForEach ){ - xForEach(p, newDb, (const char*)zName); - } - printf("done\n"); - } - if( rc!=SQLITE_DONE ){ - sqlite3_finalize(pQuery); - sqlite3_free(zQuery); - zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" - " WHERE %s ORDER BY rowid DESC", zWhere); - rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Error: (%d) %s on [%s]\n", - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), - zQuery); - goto end_schema_xfer; - } - while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ - zName = sqlite3_column_text(pQuery, 0); - zSql = sqlite3_column_text(pQuery, 1); - printf("%s... ", zName); fflush(stdout); - sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); - if( zErrMsg ){ - utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); - sqlite3_free(zErrMsg); - zErrMsg = 0; - } - if( xForEach ){ - xForEach(p, newDb, (const char*)zName); - } - printf("done\n"); - } - } -end_schema_xfer: - sqlite3_finalize(pQuery); - sqlite3_free(zQuery); -} - -/* -** Open a new database file named "zNewDb". Try to recover as much information -** as possible out of the main database (which might be corrupt) and write it -** into zNewDb. -*/ -static void tryToClone(ShellState *p, const char *zNewDb){ - int rc; - sqlite3 *newDb = 0; - if( access(zNewDb,0)==0 ){ - utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb); - return; - } - rc = sqlite3_open(zNewDb, &newDb); - if( rc ){ - utf8_printf(stderr, "Cannot create output database: %s\n", - sqlite3_errmsg(newDb)); - }else{ - sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); - sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); - tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); - tryToCloneSchema(p, newDb, "type!='table'", 0); - sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); - sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); - } - sqlite3_close(newDb); -} - -/* -** Change the output file back to stdout -*/ -static void output_reset(ShellState *p){ - if( p->outfile[0]=='|' ){ -#ifndef SQLITE_OMIT_POPEN - pclose(p->out); -#endif - }else{ - output_file_close(p->out); - } - p->outfile[0] = 0; - p->out = stdout; -} - -/* -** Run an SQL command and return the single integer result. -*/ -static int db_int(ShellState *p, const char *zSql){ - sqlite3_stmt *pStmt; - int res = 0; - sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ - res = sqlite3_column_int(pStmt,0); - } - sqlite3_finalize(pStmt); - return res; -} - -/* -** Convert a 2-byte or 4-byte big-endian integer into a native integer -*/ -static unsigned int get2byteInt(unsigned char *a){ - return (a[0]<<8) + a[1]; -} -static unsigned int get4byteInt(unsigned char *a){ - return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; -} - -/* -** Implementation of the ".info" command. -** -** Return 1 on error, 2 to exit, and 0 otherwise. -*/ -static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ - static const struct { const char *zName; int ofst; } aField[] = { - { "file change counter:", 24 }, - { "database page count:", 28 }, - { "freelist page count:", 36 }, - { "schema cookie:", 40 }, - { "schema format:", 44 }, - { "default cache size:", 48 }, - { "autovacuum top root:", 52 }, - { "incremental vacuum:", 64 }, - { "text encoding:", 56 }, - { "user version:", 60 }, - { "application id:", 68 }, - { "software version:", 96 }, - }; - static const struct { const char *zName; const char *zSql; } aQuery[] = { - { "number of tables:", - "SELECT count(*) FROM %s WHERE type='table'" }, - { "number of indexes:", - "SELECT count(*) FROM %s WHERE type='index'" }, - { "number of triggers:", - "SELECT count(*) FROM %s WHERE type='trigger'" }, - { "number of views:", - "SELECT count(*) FROM %s WHERE type='view'" }, - { "schema size:", - "SELECT total(length(sql)) FROM %s" }, - }; - sqlite3_file *pFile = 0; - int i; - char *zSchemaTab; - char *zDb = nArg>=2 ? azArg[1] : "main"; - unsigned char aHdr[100]; - open_db(p, 0); - if( p->db==0 ) return 1; - sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); - if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ - return 1; - } - i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); - if( i!=SQLITE_OK ){ - raw_printf(stderr, "unable to read database header\n"); - return 1; - } - i = get2byteInt(aHdr+16); - if( i==1 ) i = 65536; - utf8_printf(p->out, "%-20s %d\n", "database page size:", i); - utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]); - utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]); - utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); - for(i=0; iout, "%-20s %u", aField[i].zName, val); - switch( ofst ){ - case 56: { - if( val==1 ) raw_printf(p->out, " (utf8)"); - if( val==2 ) raw_printf(p->out, " (utf16le)"); - if( val==3 ) raw_printf(p->out, " (utf16be)"); - } - } - raw_printf(p->out, "\n"); - } - if( zDb==0 ){ - zSchemaTab = sqlite3_mprintf("main.sqlite_master"); - }else if( strcmp(zDb,"temp")==0 ){ - zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master"); - }else{ - zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); - } - for(i=0; iout, "%-20s %d\n", aQuery[i].zName, val); - } - sqlite3_free(zSchemaTab); - return 0; -} - -/* -** Print the current sqlite3_errmsg() value to stderr and return 1. -*/ -static int shellDatabaseError(sqlite3 *db){ - const char *zErr = sqlite3_errmsg(db); - utf8_printf(stderr, "Error: %s\n", zErr); - return 1; -} - -/* -** Print an out-of-memory message to stderr and return 1. -*/ -static int shellNomemError(void){ - raw_printf(stderr, "Error: out of memory\n"); - return 1; -} - -/* -** Compare the pattern in zGlob[] against the text in z[]. Return TRUE -** if they match and FALSE (0) if they do not match. -** -** Globbing rules: -** -** '*' Matches any sequence of zero or more characters. -** -** '?' Matches exactly one character. -** -** [...] Matches one character from the enclosed list of -** characters. -** -** [^...] Matches one character not in the enclosed list. -** -** '#' Matches any sequence of one or more digits with an -** optional + or - sign in front -** -** ' ' Any span of whitespace matches any other span of -** whitespace. -** -** Extra whitespace at the end of z[] is ignored. -*/ -static int testcase_glob(const char *zGlob, const char *z){ - int c, c2; - int invert; - int seen; - - while( (c = (*(zGlob++)))!=0 ){ - if( IsSpace(c) ){ - if( !IsSpace(*z) ) return 0; - while( IsSpace(*zGlob) ) zGlob++; - while( IsSpace(*z) ) z++; - }else if( c=='*' ){ - while( (c=(*(zGlob++))) == '*' || c=='?' ){ - if( c=='?' && (*(z++))==0 ) return 0; - } - if( c==0 ){ - return 1; - }else if( c=='[' ){ - while( *z && testcase_glob(zGlob-1,z)==0 ){ - z++; - } - return (*z)!=0; - } - while( (c2 = (*(z++)))!=0 ){ - while( c2!=c ){ - c2 = *(z++); - if( c2==0 ) return 0; - } - if( testcase_glob(zGlob,z) ) return 1; - } - return 0; - }else if( c=='?' ){ - if( (*(z++))==0 ) return 0; - }else if( c=='[' ){ - int prior_c = 0; - seen = 0; - invert = 0; - c = *(z++); - if( c==0 ) return 0; - c2 = *(zGlob++); - if( c2=='^' ){ - invert = 1; - c2 = *(zGlob++); - } - if( c2==']' ){ - if( c==']' ) seen = 1; - c2 = *(zGlob++); - } - while( c2 && c2!=']' ){ - if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ - c2 = *(zGlob++); - if( c>=prior_c && c<=c2 ) seen = 1; - prior_c = 0; - }else{ - if( c==c2 ){ - seen = 1; - } - prior_c = c2; - } - c2 = *(zGlob++); - } - if( c2==0 || (seen ^ invert)==0 ) return 0; - }else if( c=='#' ){ - if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++; - if( !IsDigit(z[0]) ) return 0; - z++; - while( IsDigit(z[0]) ){ z++; } - }else{ - if( c!=(*(z++)) ) return 0; - } - } - while( IsSpace(*z) ){ z++; } - return *z==0; -} - - -/* -** Compare the string as a command-line option with either one or two -** initial "-" characters. -*/ -static int optionMatch(const char *zStr, const char *zOpt){ - if( zStr[0]!='-' ) return 0; - zStr++; - if( zStr[0]=='-' ) zStr++; - return strcmp(zStr, zOpt)==0; -} - -/* -** Delete a file. -*/ -int shellDeleteFile(const char *zFilename){ - int rc; -#ifdef _WIN32 - wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename); - rc = _wunlink(z); - sqlite3_free(z); -#else - rc = unlink(zFilename); -#endif - return rc; -} - - -/* -** The implementation of SQL scalar function fkey_collate_clause(), used -** by the ".lint fkey-indexes" command. This scalar function is always -** called with four arguments - the parent table name, the parent column name, -** the child table name and the child column name. -** -** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col') -** -** If either of the named tables or columns do not exist, this function -** returns an empty string. An empty string is also returned if both tables -** and columns exist but have the same default collation sequence. Or, -** if both exist but the default collation sequences are different, this -** function returns the string " COLLATE ", where -** is the default collation sequence of the parent column. -*/ -static void shellFkeyCollateClause( - sqlite3_context *pCtx, - int nVal, - sqlite3_value **apVal -){ - sqlite3 *db = sqlite3_context_db_handle(pCtx); - const char *zParent; - const char *zParentCol; - const char *zParentSeq; - const char *zChild; - const char *zChildCol; - const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */ - int rc; - - assert( nVal==4 ); - zParent = (const char*)sqlite3_value_text(apVal[0]); - zParentCol = (const char*)sqlite3_value_text(apVal[1]); - zChild = (const char*)sqlite3_value_text(apVal[2]); - zChildCol = (const char*)sqlite3_value_text(apVal[3]); - - sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); - rc = sqlite3_table_column_metadata( - db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0 - ); - if( rc==SQLITE_OK ){ - rc = sqlite3_table_column_metadata( - db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0 - ); - } - - if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){ - char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq); - sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); - sqlite3_free(z); - } -} - - -/* -** The implementation of dot-command ".lint fkey-indexes". -*/ -static int lintFkeyIndexes( - ShellState *pState, /* Current shell tool state */ - char **azArg, /* Array of arguments passed to dot command */ - int nArg /* Number of entries in azArg[] */ -){ - sqlite3 *db = pState->db; /* Database handle to query "main" db of */ - FILE *out = pState->out; /* Stream to write non-error output to */ - int bVerbose = 0; /* If -verbose is present */ - int bGroupByParent = 0; /* If -groupbyparent is present */ - int i; /* To iterate through azArg[] */ - const char *zIndent = ""; /* How much to indent CREATE INDEX by */ - int rc; /* Return code */ - sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ - - /* - ** This SELECT statement returns one row for each foreign key constraint - ** in the schema of the main database. The column values are: - ** - ** 0. The text of an SQL statement similar to: - ** - ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?" - ** - ** This is the same SELECT that the foreign keys implementation needs - ** to run internally on child tables. If there is an index that can - ** be used to optimize this query, then it can also be used by the FK - ** implementation to optimize DELETE or UPDATE statements on the parent - ** table. - ** - ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by - ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema - ** contains an index that can be used to optimize the query. - ** - ** 2. Human readable text that describes the child table and columns. e.g. - ** - ** "child_table(child_key1, child_key2)" - ** - ** 3. Human readable text that describes the parent table and columns. e.g. - ** - ** "parent_table(parent_key1, parent_key2)" - ** - ** 4. A full CREATE INDEX statement for an index that could be used to - ** optimize DELETE or UPDATE statements on the parent table. e.g. - ** - ** "CREATE INDEX child_table_child_key ON child_table(child_key)" - ** - ** 5. The name of the parent table. - ** - ** These six values are used by the C logic below to generate the report. - */ - const char *zSql = - "SELECT " - " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '" - " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " - " || fkey_collate_clause(" - " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" - ", " - " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('" - " || group_concat('*=?', ' AND ') || ')'" - ", " - " s.name || '(' || group_concat(f.[from], ', ') || ')'" - ", " - " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'" - ", " - " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" - " || ' ON ' || quote(s.name) || '('" - " || group_concat(quote(f.[from]) ||" - " fkey_collate_clause(" - " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')" - " || ');'" - ", " - " f.[table] " - "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f " - "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) " - "GROUP BY s.name, f.id " - "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" - ; - const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)"; - - for(i=2; i1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ - bVerbose = 1; - } - else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){ - bGroupByParent = 1; - zIndent = " "; - } - else{ - raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n", - azArg[0], azArg[1] - ); - return SQLITE_ERROR; - } - } - - /* Register the fkey_collate_clause() SQL function */ - rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8, - 0, shellFkeyCollateClause, 0, 0 - ); - - - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); - } - if( rc==SQLITE_OK ){ - sqlite3_bind_int(pSql, 1, bGroupByParent); - } - - if( rc==SQLITE_OK ){ - int rc2; - char *zPrev = 0; - while( SQLITE_ROW==sqlite3_step(pSql) ){ - int res = -1; - sqlite3_stmt *pExplain = 0; - const char *zEQP = (const char*)sqlite3_column_text(pSql, 0); - const char *zGlob = (const char*)sqlite3_column_text(pSql, 1); - const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); - const char *zTarget = (const char*)sqlite3_column_text(pSql, 3); - const char *zCI = (const char*)sqlite3_column_text(pSql, 4); - const char *zParent = (const char*)sqlite3_column_text(pSql, 5); - - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); - if( rc!=SQLITE_OK ) break; - if( SQLITE_ROW==sqlite3_step(pExplain) ){ - const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3); - res = ( - 0==sqlite3_strglob(zGlob, zPlan) - || 0==sqlite3_strglob(zGlobIPK, zPlan) - ); - } - rc = sqlite3_finalize(pExplain); - if( rc!=SQLITE_OK ) break; - - if( res<0 ){ - raw_printf(stderr, "Error: internal error"); - break; - }else{ - if( bGroupByParent - && (bVerbose || res==0) - && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) - ){ - raw_printf(out, "-- Parent table %s\n", zParent); - sqlite3_free(zPrev); - zPrev = sqlite3_mprintf("%s", zParent); - } - - if( res==0 ){ - raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); - }else if( bVerbose ){ - raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n", - zIndent, zFrom, zTarget - ); - } - } - } - sqlite3_free(zPrev); - - if( rc!=SQLITE_OK ){ - raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); - } - - rc2 = sqlite3_finalize(pSql); - if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ - rc = rc2; - raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); - } - }else{ - raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); - } - - return rc; -} - -/* -** Implementation of ".lint" dot command. -*/ -static int lintDotCommand( - ShellState *pState, /* Current shell tool state */ - char **azArg, /* Array of arguments passed to dot command */ - int nArg /* Number of entries in azArg[] */ -){ - int n; - n = (nArg>=2 ? (int)strlen(azArg[1]) : 0); - if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; - return lintFkeyIndexes(pState, azArg, nArg); - - usage: - raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]); - raw_printf(stderr, "Where sub-commands are:\n"); - raw_printf(stderr, " fkey-indexes\n"); - return SQLITE_ERROR; -} - - -/* -** If an input line begins with "." then invoke this routine to -** process that line. -** -** Return 1 on error, 2 to exit, and 0 otherwise. -*/ -static int do_meta_command(char *zLine, ShellState *p){ - int h = 1; - int nArg = 0; - int n, c; - int rc = 0; - char *azArg[50]; - - /* Parse the input line into tokens. - */ - while( zLine[h] && nArgdb, shellAuth, p); - }else{ - sqlite3_set_authorizer(p->db, 0, 0); - } - }else -#endif - - if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) - || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) - ){ - const char *zDestFile = 0; - const char *zDb = 0; - sqlite3 *pDest; - sqlite3_backup *pBackup; - int j; - for(j=1; jdb, zDb); - if( pBackup==0 ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - sqlite3_close(pDest); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} - sqlite3_backup_finish(pBackup); - if( rc==SQLITE_DONE ){ - rc = 0; - }else{ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - rc = 1; - } - sqlite3_close(pDest); - }else - - if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ - if( nArg==2 ){ - bail_on_error = booleanValue(azArg[1]); - }else{ - raw_printf(stderr, "Usage: .bail on|off\n"); - rc = 1; - } - }else - - if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ - if( nArg==2 ){ - if( booleanValue(azArg[1]) ){ - setBinaryMode(p->out, 1); - }else{ - setTextMode(p->out, 1); - } - }else{ - raw_printf(stderr, "Usage: .binary on|off\n"); - rc = 1; - } - }else - - if( c=='c' && strcmp(azArg[0],"cd")==0 ){ - if( nArg==2 ){ -#if defined(_WIN32) || defined(WIN32) - wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]); - rc = !SetCurrentDirectoryW(z); - sqlite3_free(z); -#else - rc = chdir(azArg[1]); -#endif - if( rc ){ - utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]); - rc = 1; - } - }else{ - raw_printf(stderr, "Usage: .cd DIRECTORY\n"); - rc = 1; - } - }else - - /* The undocumented ".breakpoint" command causes a call to the no-op - ** routine named test_breakpoint(). - */ - if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ - test_breakpoint(); - }else - - if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){ - if( nArg==2 ){ - setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); - }else{ - raw_printf(stderr, "Usage: .changes on|off\n"); - rc = 1; - } - }else - - /* Cancel output redirection, if it is currently set (by .testcase) - ** Then read the content of the testcase-out.txt file and compare against - ** azArg[1]. If there are differences, report an error and exit. - */ - if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){ - char *zRes = 0; - output_reset(p); - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .check GLOB-PATTERN\n"); - rc = 2; - }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ - raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); - rc = 2; - }else if( testcase_glob(azArg[1],zRes)==0 ){ - utf8_printf(stderr, - "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", - p->zTestcase, azArg[1], zRes); - rc = 2; - }else{ - utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); - p->nCheck++; - } - sqlite3_free(zRes); - }else - - if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ - if( nArg==2 ){ - tryToClone(p, azArg[1]); - }else{ - raw_printf(stderr, "Usage: .clone FILENAME\n"); - rc = 1; - } - }else - - if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ - ShellState data; - char *zErrMsg = 0; - open_db(p, 0); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_List; - sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": "); - data.cnt = 0; - sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list", - callback, &data, &zErrMsg); - if( zErrMsg ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - } - }else - - if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ - rc = shell_dbinfo_command(p, nArg, azArg); - }else - - if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ - const char *zLike = 0; - int i; - int savedShowHeader = p->showHeader; - ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines); - for(i=1; iout, "PRAGMA foreign_keys=OFF;\n"); - raw_printf(p->out, "BEGIN TRANSACTION;\n"); - p->writableSchema = 0; - p->showHeader = 0; - /* Set writable_schema=ON since doing so forces SQLite to initialize - ** as much of the schema as it can even if the sqlite_master table is - ** corrupt. */ - sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); - p->nErr = 0; - if( zLike==0 ){ - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" - ); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE name=='sqlite_sequence'" - ); - run_table_dump_query(p, - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 - ); - }else{ - char *zSql; - zSql = sqlite3_mprintf( - "SELECT name, type, sql FROM sqlite_master " - "WHERE tbl_name LIKE %Q AND type=='table'" - " AND sql NOT NULL", zLike); - run_schema_dump_query(p,zSql); - sqlite3_free(zSql); - zSql = sqlite3_mprintf( - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL" - " AND type IN ('index','trigger','view')" - " AND tbl_name LIKE %Q", zLike); - run_table_dump_query(p, zSql, 0); - sqlite3_free(zSql); - } - if( p->writableSchema ){ - raw_printf(p->out, "PRAGMA writable_schema=OFF;\n"); - p->writableSchema = 0; - } - sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); - sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); - raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); - p->showHeader = savedShowHeader; - }else - - if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ - if( nArg==2 ){ - setOrClearFlag(p, SHFLG_Echo, azArg[1]); - }else{ - raw_printf(stderr, "Usage: .echo on|off\n"); - rc = 1; - } - }else - - if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ - if( nArg==2 ){ - if( strcmp(azArg[1],"full")==0 ){ - p->autoEQP = 2; - }else{ - p->autoEQP = booleanValue(azArg[1]); - } - }else{ - raw_printf(stderr, "Usage: .eqp on|off|full\n"); - rc = 1; - } - }else - - if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ - if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); - rc = 2; - }else - - /* The ".explain" command is automatic now. It is largely pointless. It - ** retained purely for backwards compatibility */ - if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ - int val = 1; - if( nArg>=2 ){ - if( strcmp(azArg[1],"auto")==0 ){ - val = 99; - }else{ - val = booleanValue(azArg[1]); - } - } - if( val==1 && p->mode!=MODE_Explain ){ - p->normalMode = p->mode; - p->mode = MODE_Explain; - p->autoExplain = 0; - }else if( val==0 ){ - if( p->mode==MODE_Explain ) p->mode = p->normalMode; - p->autoExplain = 0; - }else if( val==99 ){ - if( p->mode==MODE_Explain ) p->mode = p->normalMode; - p->autoExplain = 1; - } - }else - - if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ - ShellState data; - char *zErrMsg = 0; - int doStats = 0; - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_Semi; - if( nArg==2 && optionMatch(azArg[1], "indent") ){ - data.cMode = data.mode = MODE_Pretty; - nArg = 1; - } - if( nArg!=1 ){ - raw_printf(stderr, "Usage: .fullschema ?--indent?\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - rc = sqlite3_exec(p->db, - "SELECT sql FROM" - " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" - " FROM sqlite_master UNION ALL" - " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " - "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " - "ORDER BY rowid", - callback, &data, &zErrMsg - ); - if( rc==SQLITE_OK ){ - sqlite3_stmt *pStmt; - rc = sqlite3_prepare_v2(p->db, - "SELECT rowid FROM sqlite_master" - " WHERE name GLOB 'sqlite_stat[134]'", - -1, &pStmt, 0); - doStats = sqlite3_step(pStmt)==SQLITE_ROW; - sqlite3_finalize(pStmt); - } - if( doStats==0 ){ - raw_printf(p->out, "/* No STAT tables available */\n"); - }else{ - raw_printf(p->out, "ANALYZE sqlite_master;\n"); - sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'", - callback, &data, &zErrMsg); - data.cMode = data.mode = MODE_Insert; - data.zDestTable = "sqlite_stat1"; - shell_exec(p->db, "SELECT * FROM sqlite_stat1", - shell_callback, &data,&zErrMsg); - data.zDestTable = "sqlite_stat3"; - shell_exec(p->db, "SELECT * FROM sqlite_stat3", - shell_callback, &data,&zErrMsg); - data.zDestTable = "sqlite_stat4"; - shell_exec(p->db, "SELECT * FROM sqlite_stat4", - shell_callback, &data, &zErrMsg); - raw_printf(p->out, "ANALYZE sqlite_master;\n"); - } - }else - - if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ - if( nArg==2 ){ - p->showHeader = booleanValue(azArg[1]); - }else{ - raw_printf(stderr, "Usage: .headers on|off\n"); - rc = 1; - } - }else - - if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - utf8_printf(p->out, "%s", zHelp); - }else - - if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ - char *zTable; /* Insert data into this table */ - char *zFile; /* Name of file to extra content from */ - sqlite3_stmt *pStmt = NULL; /* A statement */ - int nCol; /* Number of columns in the table */ - int nByte; /* Number of bytes in an SQL string */ - int i, j; /* Loop counters */ - int needCommit; /* True to COMMIT or ROLLBACK at end */ - int nSep; /* Number of bytes in p->colSeparator[] */ - char *zSql; /* An SQL statement */ - ImportCtx sCtx; /* Reader context */ - char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ - int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */ - - if( nArg!=3 ){ - raw_printf(stderr, "Usage: .import FILE TABLE\n"); - goto meta_command_exit; - } - zFile = azArg[1]; - zTable = azArg[2]; - seenInterrupt = 0; - memset(&sCtx, 0, sizeof(sCtx)); - open_db(p, 0); - nSep = strlen30(p->colSeparator); - if( nSep==0 ){ - raw_printf(stderr, - "Error: non-null column separator required for import\n"); - return 1; - } - if( nSep>1 ){ - raw_printf(stderr, "Error: multi-character column separators not allowed" - " for import\n"); - return 1; - } - nSep = strlen30(p->rowSeparator); - if( nSep==0 ){ - raw_printf(stderr, "Error: non-null row separator required for import\n"); - return 1; - } - if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ - /* When importing CSV (only), if the row separator is set to the - ** default output row separator, change it to the default input - ** row separator. This avoids having to maintain different input - ** and output row separators. */ - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); - nSep = strlen30(p->rowSeparator); - } - if( nSep>1 ){ - raw_printf(stderr, "Error: multi-character row separators not allowed" - " for import\n"); - return 1; - } - sCtx.zFile = zFile; - sCtx.nLine = 1; - if( sCtx.zFile[0]=='|' ){ -#ifdef SQLITE_OMIT_POPEN - raw_printf(stderr, "Error: pipes are not supported in this OS\n"); - return 1; -#else - sCtx.in = popen(sCtx.zFile+1, "r"); - sCtx.zFile = ""; - xCloser = pclose; -#endif - }else{ - sCtx.in = fopen(sCtx.zFile, "rb"); - xCloser = fclose; - } - if( p->mode==MODE_Ascii ){ - xRead = ascii_read_one_field; - }else{ - xRead = csv_read_one_field; - } - if( sCtx.in==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); - return 1; - } - sCtx.cColSep = p->colSeparator[0]; - sCtx.cRowSep = p->rowSeparator[0]; - zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); - if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - xCloser(sCtx.in); - return 1; - } - nByte = strlen30(zSql); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ - if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ - char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); - char cSep = '('; - while( xRead(&sCtx) ){ - zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z); - cSep = ','; - if( sCtx.cTerm!=sCtx.cColSep ) break; - } - if( cSep=='(' ){ - sqlite3_free(zCreate); - sqlite3_free(sCtx.z); - xCloser(sCtx.in); - utf8_printf(stderr,"%s: empty file\n", sCtx.zFile); - return 1; - } - zCreate = sqlite3_mprintf("%z\n)", zCreate); - rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); - sqlite3_free(zCreate); - if( rc ){ - utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, - sqlite3_errmsg(p->db)); - sqlite3_free(sCtx.z); - xCloser(sCtx.in); - return 1; - } - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - } - sqlite3_free(zSql); - if( rc ){ - if (pStmt) sqlite3_finalize(pStmt); - utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); - xCloser(sCtx.in); - return 1; - } - nCol = sqlite3_column_count(pStmt); - sqlite3_finalize(pStmt); - pStmt = 0; - if( nCol==0 ) return 0; /* no columns, no error */ - zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); - if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - xCloser(sCtx.in); - return 1; - } - sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); - j = strlen30(zSql); - for(i=1; idb, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - if( rc ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - if (pStmt) sqlite3_finalize(pStmt); - xCloser(sCtx.in); - return 1; - } - needCommit = sqlite3_get_autocommit(p->db); - if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); - do{ - int startLine = sCtx.nLine; - for(i=0; imode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; - sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); - if( i=nCol ){ - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, - startLine, sqlite3_errmsg(p->db)); - } - } - }while( sCtx.cTerm!=EOF ); - - xCloser(sCtx.in); - sqlite3_free(sCtx.z); - sqlite3_finalize(pStmt); - if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); - }else - -#ifndef SQLITE_UNTESTABLE - if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){ - char *zSql; - char *zCollist = 0; - sqlite3_stmt *pStmt; - int tnum = 0; - int i; - if( nArg!=3 ){ - utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master" - " WHERE name='%q' AND type='index'", azArg[1]); - sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - if( sqlite3_step(pStmt)==SQLITE_ROW ){ - tnum = sqlite3_column_int(pStmt, 0); - } - sqlite3_finalize(pStmt); - if( tnum==0 ){ - utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]); - rc = 1; - goto meta_command_exit; - } - zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - i = 0; - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - char zLabel[20]; - const char *zCol = (const char*)sqlite3_column_text(pStmt,2); - i++; - if( zCol==0 ){ - if( sqlite3_column_int(pStmt,1)==-1 ){ - zCol = "_ROWID_"; - }else{ - sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i); - zCol = zLabel; - } - } - if( zCollist==0 ){ - zCollist = sqlite3_mprintf("\"%w\"", zCol); - }else{ - zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol); - } - } - sqlite3_finalize(pStmt); - zSql = sqlite3_mprintf( - "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID", - azArg[2], zCollist, zCollist); - sqlite3_free(zCollist); - rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); - if( rc==SQLITE_OK ){ - rc = sqlite3_exec(p->db, zSql, 0, 0, 0); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); - if( rc ){ - utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); - }else{ - utf8_printf(stdout, "%s;\n", zSql); - raw_printf(stdout, - "WARNING: writing to an imposter table will corrupt the index!\n" - ); - } - }else{ - raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); - rc = 1; - } - sqlite3_free(zSql); - }else -#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ - -#ifdef SQLITE_ENABLE_IOTRACE - if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ - SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); - if( iotrace && iotrace!=stdout ) fclose(iotrace); - iotrace = 0; - if( nArg<2 ){ - sqlite3IoTrace = 0; - }else if( strcmp(azArg[1], "-")==0 ){ - sqlite3IoTrace = iotracePrintf; - iotrace = stdout; - }else{ - iotrace = fopen(azArg[1], "w"); - if( iotrace==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); - sqlite3IoTrace = 0; - rc = 1; - }else{ - sqlite3IoTrace = iotracePrintf; - } - } - }else -#endif - - if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){ - static const struct { - const char *zLimitName; /* Name of a limit */ - int limitCode; /* Integer code for that limit */ - } aLimit[] = { - { "length", SQLITE_LIMIT_LENGTH }, - { "sql_length", SQLITE_LIMIT_SQL_LENGTH }, - { "column", SQLITE_LIMIT_COLUMN }, - { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH }, - { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT }, - { "vdbe_op", SQLITE_LIMIT_VDBE_OP }, - { "function_arg", SQLITE_LIMIT_FUNCTION_ARG }, - { "attached", SQLITE_LIMIT_ATTACHED }, - { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, - { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER }, - { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH }, - { "worker_threads", SQLITE_LIMIT_WORKER_THREADS }, - }; - int i, n2; - open_db(p, 0); - if( nArg==1 ){ - for(i=0; idb, aLimit[i].limitCode, -1)); - } - }else if( nArg>3 ){ - raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); - rc = 1; - goto meta_command_exit; - }else{ - int iLimit = -1; - n2 = strlen30(azArg[1]); - for(i=0; idb, aLimit[iLimit].limitCode, - (int)integerValue(azArg[2])); - } - printf("%20s %d\n", aLimit[iLimit].zLimitName, - sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); - } - }else - - if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){ - open_db(p, 0); - lintDotCommand(p, azArg, nArg); - }else - -#ifndef SQLITE_OMIT_LOAD_EXTENSION - if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ - const char *zFile, *zProc; - char *zErrMsg = 0; - if( nArg<2 ){ - raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n"); - rc = 1; - goto meta_command_exit; - } - zFile = azArg[1]; - zProc = nArg>=3 ? azArg[2] : 0; - open_db(p, 0); - rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - } - }else -#endif - - if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .log FILENAME\n"); - rc = 1; - }else{ - const char *zFile = azArg[1]; - output_file_close(p->pLog); - p->pLog = output_file_open(zFile); - } - }else - - if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ - const char *zMode = nArg>=2 ? azArg[1] : ""; - int n2 = (int)strlen(zMode); - int c2 = zMode[0]; - if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ - p->mode = MODE_Line; - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); - }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){ - p->mode = MODE_Column; - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); - }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){ - p->mode = MODE_List; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column); - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); - }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ - p->mode = MODE_Html; - }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ - p->mode = MODE_Tcl; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); - }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ - p->mode = MODE_Csv; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); - }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ - p->mode = MODE_List; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); - }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ - p->mode = MODE_Insert; - set_table_name(p, nArg>=3 ? azArg[2] : "table"); - }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){ - p->mode = MODE_Quote; - }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ - p->mode = MODE_Ascii; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); - }else if( nArg==1 ){ - raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]); - }else{ - raw_printf(stderr, "Error: mode should be one of: " - "ascii column csv html insert line list quote tabs tcl\n"); - rc = 1; - } - p->cMode = p->mode; - }else - - if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ - if( nArg==2 ){ - sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, - "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); - }else{ - raw_printf(stderr, "Usage: .nullvalue STRING\n"); - rc = 1; - } - }else - - if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ - char *zNewFilename; /* Name of the database file to open */ - int iName = 1; /* Index in azArg[] of the filename */ - int newFlag = 0; /* True to delete file before opening */ - /* Close the existing database */ - session_close_all(p); - sqlite3_close(p->db); - p->db = 0; - p->zDbFilename = 0; - sqlite3_free(p->zFreeOnClose); - p->zFreeOnClose = 0; - /* Check for command-line arguments */ - for(iName=1; iNameiName ? sqlite3_mprintf("%s", azArg[iName]) : 0; - if( zNewFilename ){ - if( newFlag ) shellDeleteFile(zNewFilename); - p->zDbFilename = zNewFilename; - open_db(p, 1); - if( p->db==0 ){ - utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); - sqlite3_free(zNewFilename); - }else{ - p->zFreeOnClose = zNewFilename; - } - } - if( p->db==0 ){ - /* As a fall-back open a TEMP database */ - p->zDbFilename = 0; - open_db(p, 0); - } - }else - - if( c=='o' - && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0) - ){ - const char *zFile = nArg>=2 ? azArg[1] : "stdout"; - if( nArg>2 ){ - utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]); - rc = 1; - goto meta_command_exit; - } - if( n>1 && strncmp(azArg[0], "once", n)==0 ){ - if( nArg<2 ){ - raw_printf(stderr, "Usage: .once FILE\n"); - rc = 1; - goto meta_command_exit; - } - p->outCount = 2; - }else{ - p->outCount = 0; - } - output_reset(p); - if( zFile[0]=='|' ){ -#ifdef SQLITE_OMIT_POPEN - raw_printf(stderr, "Error: pipes are not supported in this OS\n"); - rc = 1; - p->out = stdout; -#else - p->out = popen(zFile + 1, "w"); - if( p->out==0 ){ - utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); - p->out = stdout; - rc = 1; - }else{ - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); - } -#endif - }else{ - p->out = output_file_open(zFile); - if( p->out==0 ){ - if( strcmp(zFile,"off")!=0 ){ - utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile); - } - p->out = stdout; - rc = 1; - } else { - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); - } - } - }else - - if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){ - int i; - for(i=1; i1 ) raw_printf(p->out, " "); - utf8_printf(p->out, "%s", azArg[i]); - } - raw_printf(p->out, "\n"); - }else - - if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){ - if( nArg >= 2) { - strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); - } - if( nArg >= 3) { - strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); - } - }else - - if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ - rc = 2; - }else - - if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ - FILE *alt; - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .read FILE\n"); - rc = 1; - goto meta_command_exit; - } - alt = fopen(azArg[1], "rb"); - if( alt==0 ){ - utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); - rc = 1; - }else{ - rc = process_input(p, alt); - fclose(alt); - } - }else - - if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){ - const char *zSrcFile; - const char *zDb; - sqlite3 *pSrc; - sqlite3_backup *pBackup; - int nTimeout = 0; - - if( nArg==2 ){ - zSrcFile = azArg[1]; - zDb = "main"; - }else if( nArg==3 ){ - zSrcFile = azArg[2]; - zDb = azArg[1]; - }else{ - raw_printf(stderr, "Usage: .restore ?DB? FILE\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_open(zSrcFile, &pSrc); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); - sqlite3_close(pSrc); - return 1; - } - open_db(p, 0); - pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); - if( pBackup==0 ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - sqlite3_close(pSrc); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK - || rc==SQLITE_BUSY ){ - if( rc==SQLITE_BUSY ){ - if( nTimeout++ >= 3 ) break; - sqlite3_sleep(100); - } - } - sqlite3_backup_finish(pBackup); - if( rc==SQLITE_DONE ){ - rc = 0; - }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - raw_printf(stderr, "Error: source database is busy\n"); - rc = 1; - }else{ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - rc = 1; - } - sqlite3_close(pSrc); - }else - - - if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){ - if( nArg==2 ){ - p->scanstatsOn = booleanValue(azArg[1]); -#ifndef SQLITE_ENABLE_STMT_SCANSTATUS - raw_printf(stderr, "Warning: .scanstats not available in this build.\n"); -#endif - }else{ - raw_printf(stderr, "Usage: .scanstats on|off\n"); - rc = 1; - } - }else - - if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ - ShellText sSelect; - ShellState data; - char *zErrMsg = 0; - const char *zDiv = 0; - int iSchema = 0; - - open_db(p, 0); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_Semi; - initText(&sSelect); - if( nArg>=2 && optionMatch(azArg[1], "indent") ){ - data.cMode = data.mode = MODE_Pretty; - nArg--; - if( nArg==2 ) azArg[1] = azArg[2]; - } - if( nArg==2 && azArg[1][0]!='-' ){ - int i; - for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); - if( strcmp(azArg[1],"sqlite_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TABLE sqlite_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; - }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; - }else{ - zDiv = "("; - } - }else if( nArg==1 ){ - zDiv = "("; - }else{ - raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; - } - if( zDiv ){ - sqlite3_stmt *pStmt = 0; - rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list", - -1, &pStmt, 0); - if( rc ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - sqlite3_finalize(pStmt); - rc = 1; - goto meta_command_exit; - } - appendText(&sSelect, "SELECT sql FROM", 0); - iSchema = 0; - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - const char *zDb = (const char*)sqlite3_column_text(pStmt, 0); - char zScNum[30]; - sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema); - appendText(&sSelect, zDiv, 0); - zDiv = " UNION ALL "; - if( strcmp(zDb, "main")!=0 ){ - appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); - appendText(&sSelect, zDb, '"'); - appendText(&sSelect, ") AS sql, type, tbl_name, name, rowid,", 0); - appendText(&sSelect, zScNum, 0); - appendText(&sSelect, " AS snum, ", 0); - appendText(&sSelect, zDb, '\''); - appendText(&sSelect, " AS sname FROM ", 0); - appendText(&sSelect, zDb, '"'); - appendText(&sSelect, ".sqlite_master", 0); - }else{ - appendText(&sSelect, "SELECT sql, type, tbl_name, name, rowid, ", 0); - appendText(&sSelect, zScNum, 0); - appendText(&sSelect, " AS snum, 'main' AS sname FROM sqlite_master",0); - } - } - sqlite3_finalize(pStmt); - appendText(&sSelect, ") WHERE ", 0); - if( nArg>1 ){ - char *zQarg = sqlite3_mprintf("%Q", azArg[1]); - if( strchr(azArg[1], '.') ){ - appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0); - }else{ - appendText(&sSelect, "lower(tbl_name)", 0); - } - appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0); - appendText(&sSelect, zQarg, 0); - appendText(&sSelect, " AND ", 0); - sqlite3_free(zQarg); - } - appendText(&sSelect, "type!='meta' AND sql IS NOT NULL" - " ORDER BY snum, rowid", 0); - rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); - freeText(&sSelect); - } - if( zErrMsg ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - }else if( rc != SQLITE_OK ){ - raw_printf(stderr,"Error: querying schema information\n"); - rc = 1; - }else{ - rc = 0; - } - }else - -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - sqlite3SelectTrace = (int)integerValue(azArg[1]); - }else -#endif - -#if defined(SQLITE_ENABLE_SESSION) - if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ - OpenSession *pSession = &p->aSession[0]; - char **azCmd = &azArg[1]; - int iSes = 0; - int nCmd = nArg - 1; - int i; - if( nArg<=1 ) goto session_syntax_error; - open_db(p, 0); - if( nArg>=3 ){ - for(iSes=0; iSesnSession; iSes++){ - if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break; - } - if( iSesnSession ){ - pSession = &p->aSession[iSes]; - azCmd++; - nCmd--; - }else{ - pSession = &p->aSession[0]; - iSes = 0; - } - } - - /* .session attach TABLE - ** Invoke the sqlite3session_attach() interface to attach a particular - ** table so that it is never filtered. - */ - if( strcmp(azCmd[0],"attach")==0 ){ - if( nCmd!=2 ) goto session_syntax_error; - if( pSession->p==0 ){ - session_not_open: - raw_printf(stderr, "ERROR: No sessions are open\n"); - }else{ - rc = sqlite3session_attach(pSession->p, azCmd[1]); - if( rc ){ - raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); - rc = 0; - } - } - }else - - /* .session changeset FILE - ** .session patchset FILE - ** Write a changeset or patchset into a file. The file is overwritten. - */ - if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){ - FILE *out = 0; - if( nCmd!=2 ) goto session_syntax_error; - if( pSession->p==0 ) goto session_not_open; - out = fopen(azCmd[1], "wb"); - if( out==0 ){ - utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); - }else{ - int szChng; - void *pChng; - if( azCmd[0][0]=='c' ){ - rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); - }else{ - rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); - } - if( rc ){ - printf("Error: error code %d\n", rc); - rc = 0; - } - if( pChng - && fwrite(pChng, szChng, 1, out)!=1 ){ - raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n", - szChng); - } - sqlite3_free(pChng); - fclose(out); - } - }else - - /* .session close - ** Close the identified session - */ - if( strcmp(azCmd[0], "close")==0 ){ - if( nCmd!=1 ) goto session_syntax_error; - if( p->nSession ){ - session_close(pSession); - p->aSession[iSes] = p->aSession[--p->nSession]; - } - }else - - /* .session enable ?BOOLEAN? - ** Query or set the enable flag - */ - if( strcmp(azCmd[0], "enable")==0 ){ - int ii; - if( nCmd>2 ) goto session_syntax_error; - ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); - if( p->nSession ){ - ii = sqlite3session_enable(pSession->p, ii); - utf8_printf(p->out, "session %s enable flag = %d\n", - pSession->zName, ii); - } - }else - - /* .session filter GLOB .... - ** Set a list of GLOB patterns of table names to be excluded. - */ - if( strcmp(azCmd[0], "filter")==0 ){ - int ii, nByte; - if( nCmd<2 ) goto session_syntax_error; - if( p->nSession ){ - for(ii=0; iinFilter; ii++){ - sqlite3_free(pSession->azFilter[ii]); - } - sqlite3_free(pSession->azFilter); - nByte = sizeof(pSession->azFilter[0])*(nCmd-1); - pSession->azFilter = sqlite3_malloc( nByte ); - if( pSession->azFilter==0 ){ - raw_printf(stderr, "Error: out or memory\n"); - exit(1); - } - for(ii=1; iiazFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); - } - pSession->nFilter = ii-1; - } - }else - - /* .session indirect ?BOOLEAN? - ** Query or set the indirect flag - */ - if( strcmp(azCmd[0], "indirect")==0 ){ - int ii; - if( nCmd>2 ) goto session_syntax_error; - ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); - if( p->nSession ){ - ii = sqlite3session_indirect(pSession->p, ii); - utf8_printf(p->out, "session %s indirect flag = %d\n", - pSession->zName, ii); - } - }else - - /* .session isempty - ** Determine if the session is empty - */ - if( strcmp(azCmd[0], "isempty")==0 ){ - int ii; - if( nCmd!=1 ) goto session_syntax_error; - if( p->nSession ){ - ii = sqlite3session_isempty(pSession->p); - utf8_printf(p->out, "session %s isempty flag = %d\n", - pSession->zName, ii); - } - }else - - /* .session list - ** List all currently open sessions - */ - if( strcmp(azCmd[0],"list")==0 ){ - for(i=0; inSession; i++){ - utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName); - } - }else - - /* .session open DB NAME - ** Open a new session called NAME on the attached database DB. - ** DB is normally "main". - */ - if( strcmp(azCmd[0],"open")==0 ){ - char *zName; - if( nCmd!=3 ) goto session_syntax_error; - zName = azCmd[2]; - if( zName[0]==0 ) goto session_syntax_error; - for(i=0; inSession; i++){ - if( strcmp(p->aSession[i].zName,zName)==0 ){ - utf8_printf(stderr, "Session \"%s\" already exists\n", zName); - goto meta_command_exit; - } - } - if( p->nSession>=ArraySize(p->aSession) ){ - raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); - goto meta_command_exit; - } - pSession = &p->aSession[p->nSession]; - rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); - if( rc ){ - raw_printf(stderr, "Cannot open session: error code=%d\n", rc); - rc = 0; - goto meta_command_exit; - } - pSession->nFilter = 0; - sqlite3session_table_filter(pSession->p, session_filter, pSession); - p->nSession++; - pSession->zName = sqlite3_mprintf("%s", zName); - }else - /* If no command name matches, show a syntax error */ - session_syntax_error: - session_help(p); - }else -#endif - -#ifdef SQLITE_DEBUG - /* Undocumented commands for internal testing. Subject to change - ** without notice. */ - if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ - if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){ - int i, v; - for(i=1; iout, "%s: %d 0x%x\n", azArg[i], v, v); - } - } - if( strncmp(azArg[0]+9, "integer", n-9)==0 ){ - int i; sqlite3_int64 v; - for(i=1; iout, "%s", zBuf); - } - } - }else -#endif - - if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){ - int bIsInit = 0; /* True to initialize the SELFTEST table */ - int bVerbose = 0; /* Verbose output */ - int bSelftestExists; /* True if SELFTEST already exists */ - int i, k; /* Loop counters */ - int nTest = 0; /* Number of tests runs */ - int nErr = 0; /* Number of errors seen */ - ShellText str; /* Answer for a query */ - sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */ - - open_db(p,0); - for(i=1; idb,"main","selftest",0,0,0,0,0,0) - != SQLITE_OK ){ - bSelftestExists = 0; - }else{ - bSelftestExists = 1; - } - if( bIsInit ){ - createSelftestTable(p); - bSelftestExists = 1; - } - initText(&str); - appendText(&str, "x", 0); - for(k=bSelftestExists; k>=0; k--){ - if( k==1 ){ - rc = sqlite3_prepare_v2(p->db, - "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno", - -1, &pStmt, 0); - }else{ - rc = sqlite3_prepare_v2(p->db, - "VALUES(0,'memo','Missing SELFTEST table - default checks only','')," - " (1,'run','PRAGMA integrity_check','ok')", - -1, &pStmt, 0); - } - if( rc ){ - raw_printf(stderr, "Error querying the selftest table\n"); - rc = 1; - sqlite3_finalize(pStmt); - goto meta_command_exit; - } - for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){ - int tno = sqlite3_column_int(pStmt, 0); - const char *zOp = (const char*)sqlite3_column_text(pStmt, 1); - const char *zSql = (const char*)sqlite3_column_text(pStmt, 2); - const char *zAns = (const char*)sqlite3_column_text(pStmt, 3); - - k = 0; - if( bVerbose>0 ){ - char *zQuote = sqlite3_mprintf("%q", zSql); - printf("%d: %s %s\n", tno, zOp, zSql); - sqlite3_free(zQuote); - } - if( strcmp(zOp,"memo")==0 ){ - utf8_printf(p->out, "%s\n", zSql); - }else - if( strcmp(zOp,"run")==0 ){ - char *zErrMsg = 0; - str.n = 0; - str.z[0] = 0; - rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); - nTest++; - if( bVerbose ){ - utf8_printf(p->out, "Result: %s\n", str.z); - } - if( rc || zErrMsg ){ - nErr++; - rc = 1; - utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg); - sqlite3_free(zErrMsg); - }else if( strcmp(zAns,str.z)!=0 ){ - nErr++; - rc = 1; - utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns); - utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z); - } - }else - { - utf8_printf(stderr, - "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); - rc = 1; - break; - } - } /* End loop over rows of content from SELFTEST */ - sqlite3_finalize(pStmt); - } /* End loop over k */ - freeText(&str); - utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest); - }else - - if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ - if( nArg<2 || nArg>3 ){ - raw_printf(stderr, "Usage: .separator COL ?ROW?\n"); - rc = 1; - } - if( nArg>=2 ){ - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, - "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); - } - if( nArg>=3 ){ - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, - "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); - } - }else - - if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){ - const char *zLike = 0; /* Which table to checksum. 0 means everything */ - int i; /* Loop counter */ - int bSchema = 0; /* Also hash the schema */ - int bSeparate = 0; /* Hash each table separately */ - int iSize = 224; /* Hash algorithm to use */ - int bDebug = 0; /* Only show the query that would have run */ - sqlite3_stmt *pStmt; /* For querying tables names */ - char *zSql; /* SQL to be run */ - char *zSep; /* Separator */ - ShellText sSql; /* Complete SQL for the query to run the hash */ - ShellText sQuery; /* Set of queries used to read all content */ - open_db(p, 0); - for(i=1; i1" - " UNION ALL SELECT 'sqlite_master'" - " ORDER BY 1 collate nocase"; - }else{ - zSql = "SELECT lower(name) FROM sqlite_master" - " WHERE type='table' AND coalesce(rootpage,0)>1" - " AND name NOT LIKE 'sqlite_%'" - " ORDER BY 1 collate nocase"; - } - sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - initText(&sQuery); - initText(&sSql); - appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0); - zSep = "VALUES("; - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - const char *zTab = (const char*)sqlite3_column_text(pStmt,0); - if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue; - if( strncmp(zTab, "sqlite_",7)!=0 ){ - appendText(&sQuery,"SELECT * FROM ", 0); - appendText(&sQuery,zTab,'"'); - appendText(&sQuery," NOT INDEXED;", 0); - }else if( strcmp(zTab, "sqlite_master")==0 ){ - appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master" - " ORDER BY name;", 0); - }else if( strcmp(zTab, "sqlite_sequence")==0 ){ - appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence" - " ORDER BY name;", 0); - }else if( strcmp(zTab, "sqlite_stat1")==0 ){ - appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" - " ORDER BY tbl,idx;", 0); - }else if( strcmp(zTab, "sqlite_stat3")==0 - || strcmp(zTab, "sqlite_stat4")==0 ){ - appendText(&sQuery, "SELECT * FROM ", 0); - appendText(&sQuery, zTab, 0); - appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); - } - appendText(&sSql, zSep, 0); - appendText(&sSql, sQuery.z, '\''); - sQuery.n = 0; - appendText(&sSql, ",", 0); - appendText(&sSql, zTab, '\''); - zSep = "),("; - } - sqlite3_finalize(pStmt); - if( bSeparate ){ - zSql = sqlite3_mprintf( - "%s))" - " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" - " FROM [sha3sum$query]", - sSql.z, iSize); - }else{ - zSql = sqlite3_mprintf( - "%s))" - " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" - " FROM [sha3sum$query]", - sSql.z, iSize); - } - freeText(&sQuery); - freeText(&sSql); - if( bDebug ){ - utf8_printf(p->out, "%s\n", zSql); - }else{ - shell_exec(p->db, zSql, shell_callback, p, 0); - } - sqlite3_free(zSql); - }else - - if( c=='s' - && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) - ){ - char *zCmd; - int i, x; - if( nArg<2 ){ - raw_printf(stderr, "Usage: .system COMMAND\n"); - rc = 1; - goto meta_command_exit; - } - zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); - for(i=2; iout, "%12.12s: %s\n","echo", - azBool[ShellHasFlag(p, SHFLG_Echo)]); - utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); - utf8_printf(p->out, "%12.12s: %s\n","explain", - p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); - utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]); - utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); - utf8_printf(p->out, "%12.12s: ", "nullvalue"); - output_c_string(p->out, p->nullValue); - raw_printf(p->out, "\n"); - utf8_printf(p->out,"%12.12s: %s\n","output", - strlen30(p->outfile) ? p->outfile : "stdout"); - utf8_printf(p->out,"%12.12s: ", "colseparator"); - output_c_string(p->out, p->colSeparator); - raw_printf(p->out, "\n"); - utf8_printf(p->out,"%12.12s: ", "rowseparator"); - output_c_string(p->out, p->rowSeparator); - raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); - utf8_printf(p->out, "%12.12s: ", "width"); - for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { - raw_printf(p->out, "%d ", p->colWidth[i]); - } - raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n", "filename", - p->zDbFilename ? p->zDbFilename : ""); - }else - - if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ - if( nArg==2 ){ - p->statsOn = booleanValue(azArg[1]); - }else if( nArg==1 ){ - display_stats(p->db, p, 0); - }else{ - raw_printf(stderr, "Usage: .stats ?on|off?\n"); - rc = 1; - } - }else - - if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0) - || (c=='i' && (strncmp(azArg[0], "indices", n)==0 - || strncmp(azArg[0], "indexes", n)==0) ) - ){ - sqlite3_stmt *pStmt; - char **azResult; - int nRow, nAlloc; - int ii; - ShellText s; - initText(&s); - open_db(p, 0); - rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); - if( rc ) return shellDatabaseError(p->db); - - if( nArg>2 && c=='i' ){ - /* It is an historical accident that the .indexes command shows an error - ** when called with the wrong number of arguments whereas the .tables - ** command does not. */ - raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; - } - for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ - const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); - if( zDbName==0 ) continue; - if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0); - if( sqlite3_stricmp(zDbName, "main")==0 ){ - appendText(&s, "SELECT name FROM ", 0); - }else{ - appendText(&s, "SELECT ", 0); - appendText(&s, zDbName, '\''); - appendText(&s, "||'.'||name FROM ", 0); - } - appendText(&s, zDbName, '"'); - appendText(&s, ".sqlite_master ", 0); - if( c=='t' ){ - appendText(&s," WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%'" - " AND name LIKE ?1", 0); - }else{ - appendText(&s," WHERE type='index'" - " AND tbl_name LIKE ?1", 0); - } - } - rc = sqlite3_finalize(pStmt); - appendText(&s, " ORDER BY 1", 0); - rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0); - freeText(&s); - if( rc ) return shellDatabaseError(p->db); - - /* Run the SQL statement prepared by the above block. Store the results - ** as an array of nul-terminated strings in azResult[]. */ - nRow = nAlloc = 0; - azResult = 0; - if( nArg>1 ){ - sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); - }else{ - sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); - } - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - if( nRow>=nAlloc ){ - char **azNew; - int n2 = nAlloc*2 + 10; - azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); - if( azNew==0 ){ - rc = shellNomemError(); - break; - } - nAlloc = n2; - azResult = azNew; - } - azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); - if( 0==azResult[nRow] ){ - rc = shellNomemError(); - break; - } - nRow++; - } - if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ - rc = shellDatabaseError(p->db); - } - - /* Pretty-print the contents of array azResult[] to the output */ - if( rc==0 && nRow>0 ){ - int len, maxlen = 0; - int i, j; - int nPrintCol, nPrintRow; - for(i=0; imaxlen ) maxlen = len; - } - nPrintCol = 80/(maxlen+2); - if( nPrintCol<1 ) nPrintCol = 1; - nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; - for(i=0; iout, "%s%-*s", zSp, maxlen, - azResult[j] ? azResult[j]:""); - } - raw_printf(p->out, "\n"); - } - } - - for(ii=0; iiout = output_file_open("testcase-out.txt"); - if( p->out==0 ){ - raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); - } - if( nArg>=2 ){ - sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]); - }else{ - sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?"); - } - }else - -#ifndef SQLITE_UNTESTABLE - if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ - static const struct { - const char *zCtrlName; /* Name of a test-control option */ - int ctrlCode; /* Integer code for that option */ - } aCtrl[] = { - { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, - { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, - { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, - { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, - { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, - { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, - { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, - { "assert", SQLITE_TESTCTRL_ASSERT }, - { "always", SQLITE_TESTCTRL_ALWAYS }, - { "reserve", SQLITE_TESTCTRL_RESERVE }, - { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, - { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, - { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, - { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, - { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, - { "imposter", SQLITE_TESTCTRL_IMPOSTER }, - }; - int testctrl = -1; - int rc2 = 0; - int i, n2; - open_db(p, 0); - - /* convert testctrl text option to value. allow any unique prefix - ** of the option name, or a numerical value. */ - n2 = strlen30(azArg[1]); - for(i=0; iSQLITE_TESTCTRL_LAST) ){ - utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); - }else{ - switch(testctrl){ - - /* sqlite3_test_control(int, db, int) */ - case SQLITE_TESTCTRL_OPTIMIZATIONS: - case SQLITE_TESTCTRL_RESERVE: - if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); - rc2 = sqlite3_test_control(testctrl, p->db, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int) */ - case SQLITE_TESTCTRL_PRNG_SAVE: - case SQLITE_TESTCTRL_PRNG_RESTORE: - case SQLITE_TESTCTRL_PRNG_RESET: - case SQLITE_TESTCTRL_BYTEORDER: - if( nArg==2 ){ - rc2 = sqlite3_test_control(testctrl); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes no options\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int, uint) */ - case SQLITE_TESTCTRL_PENDING_BYTE: - if( nArg==3 ){ - unsigned int opt = (unsigned int)integerValue(azArg[2]); - rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single unsigned" - " int option\n", azArg[1]); - } - break; - - /* sqlite3_test_control(int, int) */ - case SQLITE_TESTCTRL_ASSERT: - case SQLITE_TESTCTRL_ALWAYS: - case SQLITE_TESTCTRL_NEVER_CORRUPT: - if( nArg==3 ){ - int opt = booleanValue(azArg[2]); - rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int, char *) */ -#ifdef SQLITE_N_KEYWORD - case SQLITE_TESTCTRL_ISKEYWORD: - if( nArg==3 ){ - const char *opt = azArg[2]; - rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr, - "Error: testctrl %s takes a single char * option\n", - azArg[1]); - } - break; -#endif - - case SQLITE_TESTCTRL_IMPOSTER: - if( nArg==5 ){ - rc2 = sqlite3_test_control(testctrl, p->db, - azArg[2], - integerValue(azArg[3]), - integerValue(azArg[4])); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - }else{ - raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); - } - break; - - case SQLITE_TESTCTRL_BITVEC_TEST: - case SQLITE_TESTCTRL_FAULT_INSTALL: - case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: - case SQLITE_TESTCTRL_SCRATCHMALLOC: - default: - utf8_printf(stderr, - "Error: CLI support for testctrl %s not implemented\n", - azArg[1]); - break; - } - } - }else -#endif /* !defined(SQLITE_UNTESTABLE) */ - - if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){ - open_db(p, 0); - sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); - }else - - if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ - if( nArg==2 ){ - enableTimer = booleanValue(azArg[1]); - if( enableTimer && !HAS_TIMER ){ - raw_printf(stderr, "Error: timer not available on this system.\n"); - enableTimer = 0; - } - }else{ - raw_printf(stderr, "Usage: .timer on|off\n"); - rc = 1; - } - }else - - if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ - open_db(p, 0); - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .trace FILE|off\n"); - rc = 1; - goto meta_command_exit; - } - output_file_close(p->traceOut); - p->traceOut = output_file_open(azArg[1]); -#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) - if( p->traceOut==0 ){ - sqlite3_trace_v2(p->db, 0, 0, 0); - }else{ - sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut); - } -#endif - }else - -#if SQLITE_USER_AUTHENTICATION - if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ - if( nArg<2 ){ - raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - if( strcmp(azArg[1],"login")==0 ){ - if( nArg!=4 ){ - raw_printf(stderr, "Usage: .user login USER PASSWORD\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], - (int)strlen(azArg[3])); - if( rc ){ - utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); - rc = 1; - } - }else if( strcmp(azArg[1],"add")==0 ){ - if( nArg!=5 ){ - raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_add(p->db, azArg[2], - azArg[3], (int)strlen(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - raw_printf(stderr, "User-Add failed: %d\n", rc); - rc = 1; - } - }else if( strcmp(azArg[1],"edit")==0 ){ - if( nArg!=5 ){ - raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_change(p->db, azArg[2], - azArg[3], (int)strlen(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - raw_printf(stderr, "User-Edit failed: %d\n", rc); - rc = 1; - } - }else if( strcmp(azArg[1],"delete")==0 ){ - if( nArg!=3 ){ - raw_printf(stderr, "Usage: .user delete USER\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_delete(p->db, azArg[2]); - if( rc ){ - raw_printf(stderr, "User-Delete failed: %d\n", rc); - rc = 1; - } - }else{ - raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n"); - rc = 1; - goto meta_command_exit; - } - }else -#endif /* SQLITE_USER_AUTHENTICATION */ - - if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, - sqlite3_libversion(), sqlite3_sourceid()); - }else - - if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ - const char *zDbName = nArg==2 ? azArg[1] : "main"; - sqlite3_vfs *pVfs = 0; - if( p->db ){ - sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); - if( pVfs ){ - utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); - raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); - raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); - raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); - } - } - }else - - if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){ - sqlite3_vfs *pVfs; - sqlite3_vfs *pCurrent = 0; - if( p->db ){ - sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); - } - for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ - utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, - pVfs==pCurrent ? " <--- CURRENT" : ""); - raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); - raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); - raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); - if( pVfs->pNext ){ - raw_printf(p->out, "-----------------------------------\n"); - } - } - }else - - if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ - const char *zDbName = nArg==2 ? azArg[1] : "main"; - char *zVfsName = 0; - if( p->db ){ - sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); - if( zVfsName ){ - utf8_printf(p->out, "%s\n", zVfsName); - sqlite3_free(zVfsName); - } - } - }else - -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ - sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; - }else -#endif - - if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ - int j; - assert( nArg<=ArraySize(azArg) ); - for(j=1; jcolWidth); j++){ - p->colWidth[j-1] = (int)integerValue(azArg[j]); - } - }else - - { - utf8_printf(stderr, "Error: unknown command or invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[0]); - rc = 1; - } - -meta_command_exit: - if( p->outCount ){ - p->outCount--; - if( p->outCount==0 ) output_reset(p); - } - return rc; -} - -/* -** Return TRUE if a semicolon occurs anywhere in the first N characters -** of string z[]. -*/ -static int line_contains_semicolon(const char *z, int N){ - int i; - for(i=0; idb, zSql, shell_callback, p, &zErrMsg); - END_TIMER; - if( rc || zErrMsg ){ - char zPrefix[100]; - if( in!=0 || !stdin_is_interactive ){ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, - "Error: near line %d:", startline); - }else{ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); - } - if( zErrMsg!=0 ){ - utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg); - sqlite3_free(zErrMsg); - zErrMsg = 0; - }else{ - utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); - } - return 1; - }else if( ShellHasFlag(p, SHFLG_CountChanges) ){ - raw_printf(p->out, "changes: %3d total_changes: %d\n", - sqlite3_changes(p->db), sqlite3_total_changes(p->db)); - } - return 0; -} - - -/* -** Read input from *in and process it. If *in==0 then input -** is interactive - the user is typing it it. Otherwise, input -** is coming from a file or device. A prompt is issued and history -** is saved only if input is interactive. An interrupt signal will -** cause this routine to exit immediately, unless input is interactive. -** -** Return the number of errors. -*/ -static int process_input(ShellState *p, FILE *in){ - char *zLine = 0; /* A single input line */ - char *zSql = 0; /* Accumulated SQL text */ - int nLine; /* Length of current line */ - int nSql = 0; /* Bytes of zSql[] used */ - int nAlloc = 0; /* Allocated zSql[] space */ - int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */ - int rc; /* Error code */ - int errCnt = 0; /* Number of errors seen */ - int lineno = 0; /* Current line number */ - int startline = 0; /* Line number for start of current input */ - - while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){ - fflush(p->out); - zLine = one_input_line(in, zLine, nSql>0); - if( zLine==0 ){ - /* End of input */ - if( in==0 && stdin_is_interactive ) printf("\n"); - break; - } - if( seenInterrupt ){ - if( in!=0 ) break; - seenInterrupt = 0; - } - lineno++; - if( nSql==0 && _all_whitespace(zLine) ){ - if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); - continue; - } - if( zLine && zLine[0]=='.' && nSql==0 ){ - if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); - rc = do_meta_command(zLine, p); - if( rc==2 ){ /* exit requested */ - break; - }else if( rc ){ - errCnt++; - } - continue; - } - if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){ - memcpy(zLine,";",2); - } - nLine = strlen30(zLine); - if( nSql+nLine+2>=nAlloc ){ - nAlloc = nSql+nLine+100; - zSql = realloc(zSql, nAlloc); - if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - exit(1); - } - } - nSqlPrior = nSql; - if( nSql==0 ){ - int i; - for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} - assert( nAlloc>0 && zSql!=0 ); - memcpy(zSql, zLine+i, nLine+1-i); - startline = lineno; - nSql = nLine-i; - }else{ - zSql[nSql++] = '\n'; - memcpy(zSql+nSql, zLine, nLine+1); - nSql += nLine; - } - if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) - && sqlite3_complete(zSql) ){ - errCnt += runOneSqlLine(p, zSql, in, startline); - nSql = 0; - if( p->outCount ){ - output_reset(p); - p->outCount = 0; - } - }else if( nSql && _all_whitespace(zSql) ){ - if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql); - nSql = 0; - } - } - if( nSql && !_all_whitespace(zSql) ){ - runOneSqlLine(p, zSql, in, startline); - } - free(zSql); - free(zLine); - return errCnt>0; -} - -/* -** Return a pathname which is the user's home directory. A -** 0 return indicates an error of some kind. -*/ -static char *find_home_dir(int clearFlag){ - static char *home_dir = NULL; - if( clearFlag ){ - free(home_dir); - home_dir = 0; - return 0; - } - if( home_dir ) return home_dir; - -#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \ - && !defined(__RTP__) && !defined(_WRS_KERNEL) - { - struct passwd *pwent; - uid_t uid = getuid(); - if( (pwent=getpwuid(uid)) != NULL) { - home_dir = pwent->pw_dir; - } - } -#endif - -#if defined(_WIN32_WCE) - /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() - */ - home_dir = "/"; -#else - -#if defined(_WIN32) || defined(WIN32) - if (!home_dir) { - home_dir = getenv("USERPROFILE"); - } -#endif - - if (!home_dir) { - home_dir = getenv("HOME"); - } - -#if defined(_WIN32) || defined(WIN32) - if (!home_dir) { - char *zDrive, *zPath; - int n; - zDrive = getenv("HOMEDRIVE"); - zPath = getenv("HOMEPATH"); - if( zDrive && zPath ){ - n = strlen30(zDrive) + strlen30(zPath) + 1; - home_dir = malloc( n ); - if( home_dir==0 ) return 0; - sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); - return home_dir; - } - home_dir = "c:\\"; - } -#endif - -#endif /* !_WIN32_WCE */ - - if( home_dir ){ - int n = strlen30(home_dir) + 1; - char *z = malloc( n ); - if( z ) memcpy(z, home_dir, n); - home_dir = z; - } - - return home_dir; -} - -/* -** Read input from the file given by sqliterc_override. Or if that -** parameter is NULL, take input from ~/.sqliterc -** -** Returns the number of errors. -*/ -static void process_sqliterc( - ShellState *p, /* Configuration data */ - const char *sqliterc_override /* Name of config file. NULL to use default */ -){ - char *home_dir = NULL; - const char *sqliterc = sqliterc_override; - char *zBuf = 0; - FILE *in = NULL; - - if (sqliterc == NULL) { - home_dir = find_home_dir(0); - if( home_dir==0 ){ - raw_printf(stderr, "-- warning: cannot find home directory;" - " cannot read ~/.sqliterc\n"); - return; - } - sqlite3_initialize(); - zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); - sqliterc = zBuf; - } - in = fopen(sqliterc,"rb"); - if( in ){ - if( stdin_is_interactive ){ - utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc); - } - process_input(p,in); - fclose(in); - } - sqlite3_free(zBuf); -} - -/* -** Show available command line options -*/ -static const char zOptions[] = - " -ascii set output mode to 'ascii'\n" - " -bail stop after hitting an error\n" - " -batch force batch I/O\n" - " -column set output mode to 'column'\n" - " -cmd COMMAND run \"COMMAND\" before reading stdin\n" - " -csv set output mode to 'csv'\n" - " -echo print commands before execution\n" - " -init FILENAME read/process named file\n" - " -[no]header turn headers on or off\n" -#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) - " -heap SIZE Size of heap for memsys3 or memsys5\n" -#endif - " -help show this message\n" - " -html set output mode to HTML\n" - " -interactive force interactive I/O\n" - " -line set output mode to 'line'\n" - " -list set output mode to 'list'\n" - " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" - " -mmap N default mmap size set to N\n" -#ifdef SQLITE_ENABLE_MULTIPLEX - " -multiplex enable the multiplexor VFS\n" -#endif - " -newline SEP set output row separator. Default: '\\n'\n" - " -nullvalue TEXT set text string for NULL values. Default ''\n" - " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" - " -quote set output mode to 'quote'\n" - " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" - " -separator SEP set output column separator. Default: '|'\n" - " -stats print memory stats before each finalize\n" - " -version show SQLite version\n" - " -vfs NAME use NAME as the default VFS\n" -#ifdef SQLITE_ENABLE_VFSTRACE - " -vfstrace enable tracing of all VFS calls\n" -#endif -; -static void usage(int showDetail){ - utf8_printf(stderr, - "Usage: %s [OPTIONS] FILENAME [SQL]\n" - "FILENAME is the name of an SQLite database. A new database is created\n" - "if the file does not previously exist.\n", Argv0); - if( showDetail ){ - utf8_printf(stderr, "OPTIONS include:\n%s", zOptions); - }else{ - raw_printf(stderr, "Use the -help option for additional information\n"); - } - exit(1); -} - -/* -** Initialize the state information in data -*/ -static void main_init(ShellState *data) { - memset(data, 0, sizeof(*data)); - data->normalMode = data->cMode = data->mode = MODE_List; - data->autoExplain = 1; - memcpy(data->colSeparator,SEP_Column, 2); - memcpy(data->rowSeparator,SEP_Row, 2); - data->showHeader = 0; - data->shellFlgs = SHFLG_Lookaside; - sqlite3_config(SQLITE_CONFIG_URI, 1); - sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); - sqlite3_config(SQLITE_CONFIG_MULTITHREAD); - sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); - sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); -} - -/* -** Output text to the console in a font that attracts extra attention. -*/ -#ifdef _WIN32 -static void printBold(const char *zText){ - HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; - GetConsoleScreenBufferInfo(out, &defaultScreenInfo); - SetConsoleTextAttribute(out, - FOREGROUND_RED|FOREGROUND_INTENSITY - ); - printf("%s", zText); - SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); -} -#else -static void printBold(const char *zText){ - printf("\033[1m%s\033[0m", zText); -} -#endif - -/* -** Get the argument to an --option. Throw an error and die if no argument -** is available. -*/ -static char *cmdline_option_value(int argc, char **argv, int i){ - if( i==argc ){ - utf8_printf(stderr, "%s: Error: missing argument to %s\n", - argv[0], argv[argc-1]); - exit(1); - } - return argv[i]; -} - -#ifndef SQLITE_SHELL_IS_UTF8 -# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) -# define SQLITE_SHELL_IS_UTF8 (0) -# else -# define SQLITE_SHELL_IS_UTF8 (1) -# endif -#endif - -#if SQLITE_SHELL_IS_UTF8 -int SQLITE_CDECL main(int argc, char **argv){ -#else -int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ - char **argv; -#endif - char *zErrMsg = 0; - ShellState data; - const char *zInitFile = 0; - int i; - int rc = 0; - int warnInmemoryDb = 0; - int readStdin = 1; - int nCmd = 0; - char **azCmd = 0; - - setBinaryMode(stdin, 0); - setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ - stdin_is_interactive = isatty(0); - stdout_is_console = isatty(1); - -#if USE_SYSTEM_SQLITE+0!=1 - if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ - utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", - sqlite3_sourceid(), SQLITE_SOURCE_ID); - exit(1); - } -#endif - main_init(&data); -#if !SQLITE_SHELL_IS_UTF8 - sqlite3_initialize(); - argv = sqlite3_malloc64(sizeof(argv[0])*argc); - if( argv==0 ){ - raw_printf(stderr, "out of memory\n"); - exit(1); - } - for(i=0; i=1 && argv && argv[0] ); - Argv0 = argv[0]; - - /* Make sure we have a valid signal handler early, before anything - ** else is done. - */ -#ifdef SIGINT - signal(SIGINT, interrupt_handler); -#endif - -#ifdef SQLITE_SHELL_DBNAME_PROC - { - /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name - ** of a C-function that will provide the name of the database file. Use - ** this compile-time option to embed this shell program in larger - ** applications. */ - extern void SQLITE_SHELL_DBNAME_PROC(const char**); - SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); - warnInmemoryDb = 0; - } -#endif - - /* Do an initial pass through the command-line argument to locate - ** the name of the database file, the name of the initialization file, - ** the size of the alternative malloc heap, - ** and the first command to execute. - */ - for(i=1; i0x7fff0000 ) szHeap = 0x7fff0000; - sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); -#else - (void)cmdline_option_value(argc, argv, ++i); -#endif - }else if( strcmp(z,"-scratch")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( sz>400000 ) sz = 400000; - if( sz<2500 ) sz = 2500; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( n>10 ) n = 10; - if( n<1 ) n = 1; - sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); - data.shellFlgs |= SHFLG_Scratch; - }else if( strcmp(z,"-pagecache")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( sz>70000 ) sz = 70000; - if( sz<0 ) sz = 0; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - sqlite3_config(SQLITE_CONFIG_PAGECACHE, - (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); - data.shellFlgs |= SHFLG_Pagecache; - }else if( strcmp(z,"-lookaside")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( sz<0 ) sz = 0; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( n<0 ) n = 0; - sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); - if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; -#ifdef SQLITE_ENABLE_VFSTRACE - }else if( strcmp(z,"-vfstrace")==0 ){ - extern int vfstrace_register( - const char *zTraceName, - const char *zOldVfsName, - int (*xOut)(const char*,void*), - void *pOutArg, - int makeDefault - ); - vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); -#endif -#ifdef SQLITE_ENABLE_MULTIPLEX - }else if( strcmp(z,"-multiplex")==0 ){ - extern int sqlite3_multiple_initialize(const char*,int); - sqlite3_multiplex_initialize(0, 1); -#endif - }else if( strcmp(z,"-mmap")==0 ){ - sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); - sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); - }else if( strcmp(z,"-vfs")==0 ){ - sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); - if( pVfs ){ - sqlite3_vfs_register(pVfs, 1); - }else{ - utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); - exit(1); - } - } - } - if( data.zDbFilename==0 ){ -#ifndef SQLITE_OMIT_MEMORYDB - data.zDbFilename = ":memory:"; - warnInmemoryDb = argc==1; -#else - utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0); - return 1; -#endif - } - data.out = stdout; - - /* Go ahead and open the database file if it already exists. If the - ** file does not exist, delay opening it. This prevents empty database - ** files from being created if a user mistypes the database name argument - ** to the sqlite command-line tool. - */ - if( access(data.zDbFilename, 0)==0 ){ - open_db(&data, 0); - } - - /* Process the initialization file if there is one. If no -init option - ** is given on the command line, look for a file named ~/.sqliterc and - ** try to process it. - */ - process_sqliterc(&data,zInitFile); - - /* Make a second pass through the command-line argument and set - ** options. This second pass is delayed until after the initialization - ** file is processed so that the command-line arguments will override - ** settings in the initialization file. - */ - for(i=1; i #include #include "sqlite3.h" +typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; +typedef unsigned char u8; #if SQLITE_USER_AUTHENTICATION # include "sqlite3userauth.h" #endif @@ -72,9 +75,22 @@ # if !defined(__RTP__) && !defined(_WRS_KERNEL) # include # endif -# include -# include #endif +#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__) +# include +# include +# define GETPID getpid +# if defined(__MINGW32__) +# define DIRENT dirent +# ifndef S_ISLNK +# define S_ISLNK(mode) (0) +# endif +# endif +#else +# define GETPID (int)GetCurrentProcessId +#endif +#include +#include #if HAVE_READLINE # include @@ -119,6 +135,9 @@ # ifndef access # define access(f,m) _access((f),(m)) # endif +# ifndef unlink +# define unlink _unlink +# endif # undef popen # define popen _popen # undef pclose @@ -339,6 +358,11 @@ static void endTimer(void){ */ #define UNUSED_PARAMETER(x) (void)(x) +/* +** Number of elements in an array +*/ +#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) + /* ** If the following flag is set, then command execution stops ** at an error if we are not interactive. @@ -415,6 +439,12 @@ void utf8_printf(FILE *out, const char *zFormat, ...){ # define raw_printf fprintf #endif +/* Indicate out-of-memory and exit. */ +static void shell_out_of_memory(void){ + raw_printf(stderr,"Error: out of memory\n"); + exit(1); +} + /* ** Write I/O traces to the following stream. */ @@ -538,7 +568,7 @@ static char *local_getline(char *zLine, FILE *in){ if( n+100>nLine ){ nLine = nLine*2 + 100; zLine = realloc(zLine, nLine); - if( zLine==0 ) return 0; + if( zLine==0 ) shell_out_of_memory(); } if( fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ @@ -565,10 +595,7 @@ static char *local_getline(char *zLine, FILE *in){ int nTrans = strlen30(zTrans)+1; if( nTrans>nLine ){ zLine = realloc(zLine, nTrans); - if( zLine==0 ){ - sqlite3_free(zTrans); - return 0; - } + if( zLine==0 ) shell_out_of_memory(); } memcpy(zLine, zTrans, nTrans); sqlite3_free(zTrans); @@ -611,6 +638,65 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ } return zResult; } + + +/* +** Return the value of a hexadecimal digit. Return -1 if the input +** is not a hex digit. +*/ +static int hexDigitValue(char c){ + if( c>='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; +} + +/* +** Interpret zArg as an integer value, possibly with suffixes. +*/ +static sqlite3_int64 integerValue(const char *zArg){ + sqlite3_int64 v = 0; + static const struct { char *zSuffix; int iMult; } aMult[] = { + { "KiB", 1024 }, + { "MiB", 1024*1024 }, + { "GiB", 1024*1024*1024 }, + { "KB", 1000 }, + { "MB", 1000000 }, + { "GB", 1000000000 }, + { "K", 1000 }, + { "M", 1000000 }, + { "G", 1000000000 }, + }; + int i; + int isNeg = 0; + if( zArg[0]=='-' ){ + isNeg = 1; + zArg++; + }else if( zArg[0]=='+' ){ + zArg++; + } + if( zArg[0]=='0' && zArg[1]=='x' ){ + int x; + zArg += 2; + while( (x = hexDigitValue(zArg[0]))>=0 ){ + v = (v<<4) + x; + zArg++; + } + }else{ + while( IsDigit(zArg[0]) ){ + v = v*10 + zArg[0] - '0'; + zArg++; + } + } + for(i=0; in+len>=p->nAlloc ){ p->nAlloc = p->nAlloc*2 + len + 20; p->z = realloc(p->z, p->nAlloc); - if( p->z==0 ){ - memset(p, 0, sizeof(*p)); - return; - } + if( p->z==0 ) shell_out_of_memory(); } if( quote ){ @@ -688,45 +771,79 @@ static void appendText(ShellText *p, char const *zAppend, char quote){ ** Return '"' if quoting is required. Return 0 if no quoting is required. */ static char quoteChar(const char *zName){ - /* All SQLite keywords, in alphabetical order */ - static const char *azKeywords[] = { - "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", - "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", - "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", - "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", - "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", - "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", - "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", - "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", - "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", - "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", - "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", - "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", - "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", - "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", - "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", - "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", - "WITH", "WITHOUT", - }; - int i, lwr, upr, mid, c; + int i; if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; for(i=0; zName[i]; i++){ if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; } - lwr = 0; - upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; - while( lwr<=upr ){ - mid = (lwr+upr)/2; - c = sqlite3_stricmp(azKeywords[mid], zName); - if( c==0 ) return '"'; - if( c<0 ){ - lwr = mid+1; - }else{ - upr = mid-1; - } + return sqlite3_keyword_check(zName, i) ? '"' : 0; +} + +/* +** Construct a fake object name and column list to describe the structure +** of the view, virtual table, or table valued function zSchema.zName. +*/ +static char *shellFakeSchema( + sqlite3 *db, /* The database connection containing the vtab */ + const char *zSchema, /* Schema of the database holding the vtab */ + const char *zName /* The name of the virtual table */ +){ + sqlite3_stmt *pStmt = 0; + char *zSql; + ShellText s; + char cQuote; + char *zDiv = "("; + int nRow = 0; + + zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;", + zSchema ? zSchema : "main", zName); + sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + initText(&s); + if( zSchema ){ + cQuote = quoteChar(zSchema); + if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0; + appendText(&s, zSchema, cQuote); + appendText(&s, ".", 0); + } + cQuote = quoteChar(zName); + appendText(&s, zName, cQuote); + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + const char *zCol = (const char*)sqlite3_column_text(pStmt, 1); + nRow++; + appendText(&s, zDiv, 0); + zDiv = ","; + cQuote = quoteChar(zCol); + appendText(&s, zCol, cQuote); + } + appendText(&s, ")", 0); + sqlite3_finalize(pStmt); + if( nRow==0 ){ + freeText(&s); + s.z = 0; + } + return s.z; +} + +/* +** SQL function: shell_module_schema(X) +** +** Return a fake schema for the table-valued function or eponymous virtual +** table X. +*/ +static void shellModuleSchema( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + const char *zName = (const char*)sqlite3_value_text(apVal[0]); + char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName); + UNUSED_PARAMETER(nVal); + if( zFake ){ + sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake), + -1, sqlite3_free); + free(zFake); } - return 0; } /* @@ -764,20 +881,38 @@ static void shellAddSchemaName( int i = 0; const char *zIn = (const char*)sqlite3_value_text(apVal[0]); const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); - assert( nVal==2 ); + const char *zName = (const char*)sqlite3_value_text(apVal[2]); + sqlite3 *db = sqlite3_context_db_handle(pCtx); + UNUSED_PARAMETER(nVal); if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){ int n = strlen30(aPrefix[i]); if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){ - char cQuote = quoteChar(zSchema); - char *z; - if( cQuote ){ - z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8); - }else{ - z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8); + char *z = 0; + char *zFake = 0; + if( zSchema ){ + char cQuote = quoteChar(zSchema); + if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){ + z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8); + }else{ + z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8); + } + } + if( zName + && aPrefix[i][0]=='V' + && (zFake = shellFakeSchema(db, zSchema, zName))!=0 + ){ + if( z==0 ){ + z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake); + }else{ + z = sqlite3_mprintf("%z\n/* %s */", z, zFake); + } + free(zFake); + } + if( z ){ + sqlite3_result_text(pCtx, z, -1, sqlite3_free); + return; } - sqlite3_result_text(pCtx, z, -1, sqlite3_free); - return; } } } @@ -793,9 +928,21 @@ static void shellAddSchemaName( #define SQLITE_EXTENSION_INIT1 #define SQLITE_EXTENSION_INIT2(X) (void)(X) +#if defined(_WIN32) && defined(_MSC_VER) +INCLUDE test_windirent.h +INCLUDE test_windirent.c +#define dirent DIRENT +#endif INCLUDE ../ext/misc/shathree.c INCLUDE ../ext/misc/fileio.c INCLUDE ../ext/misc/completion.c +INCLUDE ../ext/misc/appendvfs.c +#ifdef SQLITE_HAVE_ZLIB +INCLUDE ../ext/misc/zipfile.c +INCLUDE ../ext/misc/sqlar.c +#endif +INCLUDE ../ext/expert/sqlite3expert.h +INCLUDE ../ext/expert/sqlite3expert.c #if defined(SQLITE_ENABLE_SESSION) /* @@ -822,6 +969,29 @@ struct SavedModeInfo { int colWidth[100]; /* Column widths prior to ".explain on" */ }; +typedef struct ExpertInfo ExpertInfo; +struct ExpertInfo { + sqlite3expert *pExpert; + int bVerbose; +}; + +/* A single line in the EQP output */ +typedef struct EQPGraphRow EQPGraphRow; +struct EQPGraphRow { + int iEqpId; /* ID for this row */ + int iParentId; /* ID of the parent row */ + EQPGraphRow *pNext; /* Next row in sequence */ + char zText[1]; /* Text to display for this row */ +}; + +/* All EQP output is collected into an instance of the following */ +typedef struct EQPGraph EQPGraph; +struct EQPGraph { + EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */ + EQPGraphRow *pLast; /* Last element of the pRow list */ + char zPrefix[100]; /* Graph prefix */ +}; + /* ** State information about the database connection is contained in an ** instance of the following structure. @@ -829,16 +999,22 @@ struct SavedModeInfo { typedef struct ShellState ShellState; struct ShellState { sqlite3 *db; /* The database */ - int autoExplain; /* Automatically turn on .explain mode */ - int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ - int statsOn; /* True to display memory stats before each finalize */ - int scanstatsOn; /* True to display scan stats before each finalize */ + u8 autoExplain; /* Automatically turn on .explain mode */ + u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ + u8 autoEQPtest; /* autoEQP is in test mode */ + u8 statsOn; /* True to display memory stats before each finalize */ + u8 scanstatsOn; /* True to display scan stats before each finalize */ + u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ + u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ + u8 nEqpLevel; /* Depth of the EQP output graph */ + unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ + int modePrior; /* Saved mode */ int cMode; /* temporary output mode for the current query */ int normalMode; /* Output mode before ".explain on" */ int writableSchema; /* True if PRAGMA writable_schema=ON */ @@ -846,9 +1022,12 @@ struct ShellState { int nCheck; /* Number of ".check" commands run */ unsigned shellFlgs; /* Various flags */ char *zDestTable; /* Name of destination table when MODE_Insert */ + char *zTempFile; /* Temporary file that might need deleting */ char zTestcase[30]; /* Name of current test case */ char colSeparator[20]; /* Column separator character for several modes */ char rowSeparator[20]; /* Row separator character for MODE_Ascii */ + char colSepPrior[20]; /* Saved column separator */ + char rowSepPrior[20]; /* Saved row separator */ int colWidth[100]; /* Requested width of each column when in column mode*/ int actualWidth[100]; /* Actual width of each column */ char nullValue[20]; /* The text to print when a NULL comes back from @@ -862,23 +1041,40 @@ struct ShellState { int *aiIndent; /* Array of indents used in MODE_Explain */ int nIndent; /* Size of array aiIndent[] */ int iIndent; /* Index of current op in aiIndent[] */ + EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ #if defined(SQLITE_ENABLE_SESSION) int nSession; /* Number of active sessions */ OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ #endif + ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ }; + +/* Allowed values for ShellState.autoEQP +*/ +#define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */ +#define AUTOEQP_on 1 /* Automatic EQP is on */ +#define AUTOEQP_trigger 2 /* On and also show plans for triggers */ +#define AUTOEQP_full 3 /* Show full EXPLAIN */ + +/* Allowed values for ShellState.openMode +*/ +#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ +#define SHELL_OPEN_NORMAL 1 /* Normal database file */ +#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ +#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ +#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ + /* ** These are the allowed shellFlgs values */ -#define SHFLG_Scratch 0x00000001 /* The --scratch option is used */ -#define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */ -#define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ -#define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ -#define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ -#define SHFLG_Newlines 0x00000020 /* .dump --newline flag */ -#define SHFLG_CountChanges 0x00000040 /* .changes setting */ -#define SHFLG_Echo 0x00000080 /* .echo or --echo setting */ +#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */ +#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */ +#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */ +#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */ +#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ +#define SHFLG_CountChanges 0x00000020 /* .changes setting */ +#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ /* ** Macros for testing and setting shellFlgs @@ -902,6 +1098,7 @@ struct ShellState { #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ #define MODE_Pretty 11 /* Pretty-print schemas */ +#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */ static const char *modeDescr[] = { "line", @@ -916,6 +1113,7 @@ static const char *modeDescr[] = { "explain", "ascii", "prettyprint", + "eqp" }; /* @@ -931,11 +1129,6 @@ static const char *modeDescr[] = { #define SEP_Unit "\x1F" #define SEP_Record "\x1E" -/* -** Number of elements in an array -*/ -#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) - /* ** A callback for the sqlite3_log() interface. */ @@ -946,6 +1139,181 @@ static void shellLog(void *pArg, int iErrCode, const char *zMsg){ fflush(p->pLog); } +/* +** SQL function: shell_putsnl(X) +** +** Write the text X to the screen (or whatever output is being directed) +** adding a newline at the end, and then return X. +*/ +static void shellPutsFunc( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + ShellState *p = (ShellState*)sqlite3_user_data(pCtx); + (void)nVal; + utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0])); + sqlite3_result_value(pCtx, apVal[0]); +} + +/* +** SQL function: edit(VALUE) +** edit(VALUE,EDITOR) +** +** These steps: +** +** (1) Write VALUE into a temporary file. +** (2) Run program EDITOR on that temporary file. +** (3) Read the temporary file back and return its content as the result. +** (4) Delete the temporary file +** +** If the EDITOR argument is omitted, use the value in the VISUAL +** environment variable. If still there is no EDITOR, through an error. +** +** Also throw an error if the EDITOR program returns a non-zero exit code. +*/ +#ifndef SQLITE_NOHAVE_SYSTEM +static void editFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zEditor; + char *zTempFile = 0; + sqlite3 *db; + char *zCmd = 0; + int bBin; + int rc; + int hasCRNL = 0; + FILE *f = 0; + sqlite3_int64 sz; + sqlite3_int64 x; + unsigned char *p = 0; + + if( argc==2 ){ + zEditor = (const char*)sqlite3_value_text(argv[1]); + }else{ + zEditor = getenv("VISUAL"); + } + if( zEditor==0 ){ + sqlite3_result_error(context, "no editor for edit()", -1); + return; + } + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + sqlite3_result_error(context, "NULL input to edit()", -1); + return; + } + db = sqlite3_context_db_handle(context); + zTempFile = 0; + sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile); + if( zTempFile==0 ){ + sqlite3_uint64 r = 0; + sqlite3_randomness(sizeof(r), &r); + zTempFile = sqlite3_mprintf("temp%llx", r); + if( zTempFile==0 ){ + sqlite3_result_error_nomem(context); + return; + } + } + bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; + /* When writing the file to be edited, do \n to \r\n conversions on systems + ** that want \r\n line endings */ + f = fopen(zTempFile, bBin ? "wb" : "w"); + if( f==0 ){ + sqlite3_result_error(context, "edit() cannot open temp file", -1); + goto edit_func_end; + } + sz = sqlite3_value_bytes(argv[0]); + if( bBin ){ + x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f); + }else{ + const char *z = (const char*)sqlite3_value_text(argv[0]); + /* Remember whether or not the value originally contained \r\n */ + if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1; + x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f); + } + fclose(f); + f = 0; + if( x!=sz ){ + sqlite3_result_error(context, "edit() could not write the whole file", -1); + goto edit_func_end; + } + zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile); + if( zCmd==0 ){ + sqlite3_result_error_nomem(context); + goto edit_func_end; + } + rc = system(zCmd); + sqlite3_free(zCmd); + if( rc ){ + sqlite3_result_error(context, "EDITOR returned non-zero", -1); + goto edit_func_end; + } + f = fopen(zTempFile, "rb"); + if( f==0 ){ + sqlite3_result_error(context, + "edit() cannot reopen temp file after edit", -1); + goto edit_func_end; + } + fseek(f, 0, SEEK_END); + sz = ftell(f); + rewind(f); + p = sqlite3_malloc64( sz+(bBin==0) ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + goto edit_func_end; + } + x = fread(p, 1, sz, f); + fclose(f); + f = 0; + if( x!=sz ){ + sqlite3_result_error(context, "could not read back the whole file", -1); + goto edit_func_end; + } + if( bBin ){ + sqlite3_result_blob64(context, p, sz, sqlite3_free); + }else{ + sqlite3_int64 i, j; + if( hasCRNL ){ + /* If the original contains \r\n then do no conversions back to \n */ + j = sz; + }else{ + /* If the file did not originally contain \r\n then convert any new + ** \r\n back into \n */ + for(i=j=0; imodePrior = p->mode; + memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator)); + memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator)); +} +static void outputModePop(ShellState *p){ + p->mode = p->modePrior; + memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator)); + memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator)); +} + /* ** Output the given string as a hex-encoded blob (eg. X'1234' ) */ @@ -1191,12 +1559,9 @@ static void output_csv(ShellState *p, const char *z, int bSep){ } } if( i==0 ){ - putc('"', out); - for(i=0; z[i]; i++){ - if( z[i]=='"' ) putc('"', out); - putc(z[i], out); - } - putc('"', out); + char *zQuoted = sqlite3_mprintf("\"%w\"", z); + utf8_printf(out, "%s", zQuoted); + sqlite3_free(zQuoted); }else{ utf8_printf(out, "%s", z); } @@ -1206,7 +1571,6 @@ static void output_csv(ShellState *p, const char *z, int bSep){ } } -#ifdef SIGINT /* ** This routine runs when the user presses Ctrl-C */ @@ -1216,6 +1580,20 @@ static void interrupt_handler(int NotUsed){ if( seenInterrupt>2 ) exit(1); if( globalDb ) sqlite3_interrupt(globalDb); } + +#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) +/* +** This routine runs for console events (e.g. Ctrl-C) on Win32 +*/ +static BOOL WINAPI ConsoleCtrlHandler( + DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */ +){ + if( dwCtrlType==CTRL_C_EVENT ){ + interrupt_handler(0); + return TRUE; + } + return FALSE; +} #endif #ifndef SQLITE_OMIT_AUTHORIZATION @@ -1285,6 +1663,108 @@ static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ z[n] = c; } +/* +** Return true if string z[] has nothing but whitespace and comments to the +** end of the first line. +*/ +static int wsToEol(const char *z){ + int i; + for(i=0; z[i]; i++){ + if( z[i]=='\n' ) return 1; + if( IsSpace(z[i]) ) continue; + if( z[i]=='-' && z[i+1]=='-' ) return 1; + return 0; + } + return 1; +} + +/* +** Add a new entry to the EXPLAIN QUERY PLAN data +*/ +static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){ + EQPGraphRow *pNew; + int nText = strlen30(zText); + if( p->autoEQPtest ){ + utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText); + } + pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); + if( pNew==0 ) shell_out_of_memory(); + pNew->iEqpId = iEqpId; + pNew->iParentId = p2; + memcpy(pNew->zText, zText, nText+1); + pNew->pNext = 0; + if( p->sGraph.pLast ){ + p->sGraph.pLast->pNext = pNew; + }else{ + p->sGraph.pRow = pNew; + } + p->sGraph.pLast = pNew; +} + +/* +** Free and reset the EXPLAIN QUERY PLAN data that has been collected +** in p->sGraph. +*/ +static void eqp_reset(ShellState *p){ + EQPGraphRow *pRow, *pNext; + for(pRow = p->sGraph.pRow; pRow; pRow = pNext){ + pNext = pRow->pNext; + sqlite3_free(pRow); + } + memset(&p->sGraph, 0, sizeof(p->sGraph)); +} + +/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after +** pOld, or return the first such line if pOld is NULL +*/ +static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){ + EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow; + while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext; + return pRow; +} + +/* Render a single level of the graph that has iEqpId as its parent. Called +** recursively to render sublevels. +*/ +static void eqp_render_level(ShellState *p, int iEqpId){ + EQPGraphRow *pRow, *pNext; + int n = strlen30(p->sGraph.zPrefix); + char *z; + for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ + pNext = eqp_next_row(p, iEqpId, pRow); + z = pRow->zText; + utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z); + if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){ + memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); + eqp_render_level(p, pRow->iEqpId); + p->sGraph.zPrefix[n] = 0; + } + } +} + +/* +** Display and reset the EXPLAIN QUERY PLAN data +*/ +static void eqp_render(ShellState *p){ + EQPGraphRow *pRow = p->sGraph.pRow; + if( pRow ){ + if( pRow->zText[0]=='-' ){ + if( pRow->pNext==0 ){ + eqp_reset(p); + return; + } + utf8_printf(p->out, "%s\n", pRow->zText+3); + p->sGraph.pRow = pRow->pNext; + sqlite3_free(pRow); + }else{ + utf8_printf(p->out, "QUERY PLAN\n"); + } + p->sGraph.zPrefix[0] = 0; + eqp_render_level(p, 0); + eqp_reset(p); + } +} + /* ** This is the callback routine that the shell ** invokes for each row of a query result. @@ -1299,6 +1779,7 @@ static int shell_callback( int i; ShellState *p = (ShellState*)pArg; + if( azArg==0 ) return 0; switch( p->cMode ){ case MODE_Line: { int w = 5; @@ -1413,6 +1894,7 @@ static int shell_callback( for(i=0; IsSpace(z[i]); i++){} for(; (c = z[i])!=0; i++){ if( IsSpace(c) ){ + if( z[j-1]=='\r' ) z[j-1] = '\n'; if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ j--; @@ -1422,13 +1904,15 @@ static int shell_callback( while( j>0 && IsSpace(z[j-1]) ){ j--; } z[j] = 0; if( strlen30(z)>=79 ){ - for(i=j=0; (c = z[i])!=0; i++){ + for(i=j=0; (c = z[i])!=0; i++){ /* Copy changes from z[i] back to z[j] */ if( c==cEnd ){ cEnd = 0; }else if( c=='"' || c=='\'' || c=='`' ){ cEnd = c; }else if( c=='[' ){ cEnd = ']'; + }else if( c=='-' && z[i+1]=='-' ){ + cEnd = '\n'; }else if( c=='(' ){ nParen++; }else if( c==')' ){ @@ -1439,7 +1923,9 @@ static int shell_callback( } } z[j++] = c; - if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ + if( nParen==1 && cEnd==0 + && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1))) + ){ if( c=='\n' ) j--; printSchemaLineN(p->out, z, j, "\n "); j = 0; @@ -1559,8 +2045,16 @@ static int shell_callback( }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); - sqlite3_snprintf(50,z,"%!.20g", r); - raw_printf(p->out, "%s", z); + sqlite3_uint64 ur; + memcpy(&ur,&r,sizeof(r)); + if( ur==0x7ff0000000000000LL ){ + raw_printf(p->out, "1e999"); + }else if( ur==0xfff0000000000000LL ){ + raw_printf(p->out, "-1e999"); + }else{ + sqlite3_snprintf(50,z,"%!.20g", r); + raw_printf(p->out, "%s", z); + } }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); @@ -1628,6 +2122,10 @@ static int shell_callback( utf8_printf(p->out, "%s", p->rowSeparator); break; } + case MODE_EQP: { + eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]); + break; + } } return 0; } @@ -1649,6 +2147,7 @@ static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ ShellText *p = (ShellText*)pArg; int i; UNUSED_PARAMETER(az); + if( azArg==0 ) return 0; if( p->n ) appendText(p, "|", 0); for(i=0; izDestTable ){ @@ -1725,10 +2224,7 @@ static void set_table_name(ShellState *p, const char *zName){ n = strlen30(zName); if( cQuote ) n += n+2; z = p->zDestTable = malloc( n+1 ); - if( z==0 ){ - raw_printf(stderr,"Error: out of memory\n"); - exit(1); - } + if( z==0 ) shell_out_of_memory(); n = 0; if( cQuote ) z[n++] = cQuote; for(i=0; zName[i]; i++){ @@ -1836,7 +2332,7 @@ static void displayLinuxIoStats(FILE *out){ }; int i; for(i=0; iout==0 ) return 0; + out = pArg->out; - if( pArg && pArg->out ){ - displayStatLine(pArg, "Memory Used:", - "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); - displayStatLine(pArg, "Number of Outstanding Allocations:", - "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); - if( pArg->shellFlgs & SHFLG_Pagecache ){ - displayStatLine(pArg, "Number of Pcache Pages Used:", - "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); - } - displayStatLine(pArg, "Number of Pcache Overflow Bytes:", - "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); - if( pArg->shellFlgs & SHFLG_Scratch ){ - displayStatLine(pArg, "Number of Scratch Allocations Used:", - "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); - } - displayStatLine(pArg, "Number of Scratch Overflow Bytes:", - "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); - displayStatLine(pArg, "Largest Allocation:", - "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); - displayStatLine(pArg, "Largest Pcache Allocation:", - "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); - displayStatLine(pArg, "Largest Scratch Allocation:", - "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); -#ifdef YYTRACKMAXSTACKDEPTH - displayStatLine(pArg, "Deepest Parser Stack:", - "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); + if( pArg->pStmt && (pArg->statsOn & 2) ){ + int nCol, i, x; + sqlite3_stmt *pStmt = pArg->pStmt; + char z[100]; + nCol = sqlite3_column_count(pStmt); + raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol); + for(i=0; iout && db ){ + displayStatLine(pArg, "Memory Used:", + "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); + displayStatLine(pArg, "Number of Outstanding Allocations:", + "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); + if( pArg->shellFlgs & SHFLG_Pagecache ){ + displayStatLine(pArg, "Number of Pcache Pages Used:", + "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); + } + displayStatLine(pArg, "Number of Pcache Overflow Bytes:", + "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); + displayStatLine(pArg, "Largest Allocation:", + "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); + displayStatLine(pArg, "Largest Pcache Allocation:", + "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); +#ifdef YYTRACKMAXSTACKDEPTH + displayStatLine(pArg, "Deepest Parser Stack:", + "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); +#endif + + if( db ){ if( pArg->shellFlgs & SHFLG_Lookaside ){ iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, @@ -1948,6 +2461,9 @@ static int display_stats( sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); raw_printf(pArg->out, "Page cache writes: %d\n", iCur); iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); + raw_printf(pArg->out, "Page cache spills: %d\n", iCur); + iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur); @@ -1957,7 +2473,7 @@ static int display_stats( iCur); } - if( pArg && pArg->out && db && pArg->pStmt ){ + if( pArg->pStmt ){ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset); raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); @@ -1967,6 +2483,12 @@ static int display_stats( raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset); + raw_printf(pArg->out, "Reprepare operations: %d\n", iCur); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); + raw_printf(pArg->out, "Number of times run: %d\n", iCur); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); + raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur); } #ifdef __linux__ @@ -2065,8 +2587,7 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ int iOp; /* Index of operation in p->aiIndent[] */ - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", - "NextIfOpen", "PrevIfOpen", 0 }; + const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 }; const char *azGoto[] = { "Goto", 0 }; @@ -2116,7 +2637,9 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ } nAlloc += 100; p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); + if( p->aiIndent==0 ) shell_out_of_memory(); abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); + if( abYield==0 ) shell_out_of_memory(); } abYield[iOp] = str_in_array(zOp, azYield); p->aiIndent[iOp] = 0; @@ -2182,8 +2705,7 @@ static void restore_debug_trace_modes(void){ */ static void exec_prepared_stmt( ShellState *pArg, /* Pointer to ShellState */ - sqlite3_stmt *pStmt, /* Statment to run */ - int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */ + sqlite3_stmt *pStmt /* Statment to run */ ){ int rc; @@ -2193,58 +2715,182 @@ static void exec_prepared_stmt( rc = sqlite3_step(pStmt); /* if we have a result set... */ if( SQLITE_ROW == rc ){ - /* if we have a callback... */ - if( xCallback ){ - /* allocate space for col name ptr, value ptr, and type */ - int nCol = sqlite3_column_count(pStmt); - void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); - if( !pData ){ - rc = SQLITE_NOMEM; - }else{ - char **azCols = (char **)pData; /* Names of result columns */ - char **azVals = &azCols[nCol]; /* Results */ - int *aiTypes = (int *)&azVals[nCol]; /* Result types */ - int i, x; - assert(sizeof(int) <= sizeof(char *)); - /* save off ptrs to column names */ - for(i=0; icMode==MODE_Insert ){ - azVals[i] = ""; - }else{ - azVals[i] = (char*)sqlite3_column_text(pStmt, i); - } - if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ - rc = SQLITE_NOMEM; - break; /* from for */ - } - } /* end for */ - - /* if data and types extracted successfully... */ - if( SQLITE_ROW == rc ){ - /* call the supplied callback with the result row data */ - if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ - rc = SQLITE_ABORT; - }else{ - rc = sqlite3_step(pStmt); - } - } - } while( SQLITE_ROW == rc ); - sqlite3_free(pData); - } + /* allocate space for col name ptr, value ptr, and type */ + int nCol = sqlite3_column_count(pStmt); + void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); + if( !pData ){ + rc = SQLITE_NOMEM; }else{ + char **azCols = (char **)pData; /* Names of result columns */ + char **azVals = &azCols[nCol]; /* Results */ + int *aiTypes = (int *)&azVals[nCol]; /* Result types */ + int i, x; + assert(sizeof(int) <= sizeof(char *)); + /* save off ptrs to column names */ + for(i=0; icMode==MODE_Insert ){ + azVals[i] = ""; + }else{ + azVals[i] = (char*)sqlite3_column_text(pStmt, i); + } + if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ + rc = SQLITE_NOMEM; + break; /* from for */ + } + } /* end for */ + + /* if data and types extracted successfully... */ + if( SQLITE_ROW == rc ){ + /* call the supplied callback with the result row data */ + if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){ + rc = SQLITE_ABORT; + }else{ + rc = sqlite3_step(pStmt); + } + } + } while( SQLITE_ROW == rc ); + sqlite3_free(pData); } } } +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** This function is called to process SQL if the previous shell command +** was ".expert". It passes the SQL in the second argument directly to +** the sqlite3expert object. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error +** code. In this case, (*pzErr) may be set to point to a buffer containing +** an English language error message. It is the responsibility of the +** caller to eventually free this buffer using sqlite3_free(). +*/ +static int expertHandleSQL( + ShellState *pState, + const char *zSql, + char **pzErr +){ + assert( pState->expert.pExpert ); + assert( pzErr==0 || *pzErr==0 ); + return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr); +} + +/* +** This function is called either to silently clean up the object +** created by the ".expert" command (if bCancel==1), or to generate a +** report from it and then clean it up (if bCancel==0). +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error +** code. In this case, (*pzErr) may be set to point to a buffer containing +** an English language error message. It is the responsibility of the +** caller to eventually free this buffer using sqlite3_free(). +*/ +static int expertFinish( + ShellState *pState, + int bCancel, + char **pzErr +){ + int rc = SQLITE_OK; + sqlite3expert *p = pState->expert.pExpert; + assert( p ); + assert( bCancel || pzErr==0 || *pzErr==0 ); + if( bCancel==0 ){ + FILE *out = pState->out; + int bVerbose = pState->expert.bVerbose; + + rc = sqlite3_expert_analyze(p, pzErr); + if( rc==SQLITE_OK ){ + int nQuery = sqlite3_expert_count(p); + int i; + + if( bVerbose ){ + const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES); + raw_printf(out, "-- Candidates -----------------------------\n"); + raw_printf(out, "%s\n", zCand); + } + for(i=0; iexpert.pExpert = 0; + return rc; +} + +/* +** Implementation of ".expert" dot command. +*/ +static int expertDotCommand( + ShellState *pState, /* Current shell tool state */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ +){ + int rc = SQLITE_OK; + char *zErr = 0; + int i; + int iSample = 0; + + assert( pState->expert.pExpert==0 ); + memset(&pState->expert, 0, sizeof(ExpertInfo)); + + for(i=1; rc==SQLITE_OK && i=2 && 0==strncmp(z, "-verbose", n) ){ + pState->expert.bVerbose = 1; + } + else if( n>=2 && 0==strncmp(z, "-sample", n) ){ + if( i==(nArg-1) ){ + raw_printf(stderr, "option requires an argument: %s\n", z); + rc = SQLITE_ERROR; + }else{ + iSample = (int)integerValue(azArg[++i]); + if( iSample<0 || iSample>100 ){ + raw_printf(stderr, "value out of range: %s\n", azArg[i]); + rc = SQLITE_ERROR; + } + } + } + else{ + raw_printf(stderr, "unknown option: %s\n", z); + rc = SQLITE_ERROR; + } + } + + if( rc==SQLITE_OK ){ + pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); + if( pState->expert.pExpert==0 ){ + raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr); + rc = SQLITE_ERROR; + }else{ + sqlite3_expert_config( + pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample + ); + } + } + + return rc; +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + /* ** Execute a statement or set of statements. Print ** any result rows/columns depending on the current mode @@ -2255,22 +2901,27 @@ static void exec_prepared_stmt( ** and callback data argument. */ static int shell_exec( - sqlite3 *db, /* An open database */ - const char *zSql, /* SQL to be evaluated */ - int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ - /* (not the same as sqlite3_exec) */ ShellState *pArg, /* Pointer to ShellState */ + const char *zSql, /* SQL to be evaluated */ char **pzErrMsg /* Error msg written here */ ){ sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ int rc = SQLITE_OK; /* Return Code */ int rc2; const char *zLeftover; /* Tail of unprocessed SQL */ + sqlite3 *db = pArg->db; if( pzErrMsg ){ *pzErrMsg = NULL; } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pArg->expert.pExpert ){ + rc = expertHandleSQL(pArg, zSql, pzErrMsg); + return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); + } +#endif + while( zSql[0] && (SQLITE_OK == rc) ){ static const char *zStmtSql; rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); @@ -2304,42 +2955,61 @@ static int shell_exec( if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){ sqlite3_stmt *pExplain; char *zEQP; + int triggerEQP = 0; disable_debug_trace_modes(); + sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP); + if( pArg->autoEQP>=AUTOEQP_trigger ){ + sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0); + } zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); if( rc==SQLITE_OK ){ while( sqlite3_step(pExplain)==SQLITE_ROW ){ - raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0)); - raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); - raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); - utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); + const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3); + int iEqpId = sqlite3_column_int(pExplain, 0); + int iParentId = sqlite3_column_int(pExplain, 1); + if( zEQPLine[0]=='-' ) eqp_render(pArg); + eqp_append(pArg, iEqpId, iParentId, zEQPLine); } + eqp_render(pArg); } sqlite3_finalize(pExplain); sqlite3_free(zEQP); - if( pArg->autoEQP>=2 ){ + if( pArg->autoEQP>=AUTOEQP_full ){ /* Also do an EXPLAIN for ".eqp full" mode */ zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); if( rc==SQLITE_OK ){ pArg->cMode = MODE_Explain; explain_data_prepare(pArg, pExplain); - exec_prepared_stmt(pArg, pExplain, xCallback); + exec_prepared_stmt(pArg, pExplain); explain_data_delete(pArg); } sqlite3_finalize(pExplain); sqlite3_free(zEQP); } + if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ + sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); + /* Reprepare pStmt before reactiving trace modes */ + sqlite3_finalize(pStmt); + sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( pArg ) pArg->pStmt = pStmt; + } restore_debug_trace_modes(); } if( pArg ){ pArg->cMode = pArg->mode; - if( pArg->autoExplain - && sqlite3_column_count(pStmt)==8 - && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 - ){ - pArg->cMode = MODE_Explain; + if( pArg->autoExplain ){ + if( sqlite3_column_count(pStmt)==8 + && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 + ){ + pArg->cMode = MODE_Explain; + } + if( sqlite3_column_count(pStmt)==4 + && sqlite3_strlike("EXPLAIN QUERY PLAN%", zStmtSql,0)==0 ){ + pArg->cMode = MODE_EQP; + } } /* If the shell is currently in ".explain" mode, gather the extra @@ -2349,8 +3019,9 @@ static int shell_exec( } } - exec_prepared_stmt(pArg, pStmt, xCallback); + exec_prepared_stmt(pArg, pStmt); explain_data_delete(pArg); + eqp_render(pArg); /* print usage stats if stats on */ if( pArg && pArg->statsOn ){ @@ -2428,10 +3099,7 @@ static char **tableColumnList(ShellState *p, const char *zTab){ if( nCol>=nAlloc-2 ){ nAlloc = nAlloc*2 + nCol + 10; azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); - if( azCol==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - exit(1); - } + if( azCol==0 ) shell_out_of_memory(); } azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); if( sqlite3_column_int(pStmt, 5) ){ @@ -2447,6 +3115,7 @@ static char **tableColumnList(ShellState *p, const char *zTab){ } } sqlite3_finalize(pStmt); + if( azCol==0 ) return 0; azCol[0] = 0; azCol[nCol+1] = 0; @@ -2530,7 +3199,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ ShellState *p = (ShellState *)pArg; UNUSED_PARAMETER(azNotUsed); - if( nArg!=3 ) return 1; + if( nArg!=3 || azArg==0 ) return 0; zTable = azArg[0]; zType = azArg[1]; zSql = azArg[2]; @@ -2611,11 +3280,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ savedMode = p->mode; p->zDestTable = sTable.z; p->mode = p->cMode = MODE_Insert; - rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); + rc = shell_exec(p, sSelect.z, 0); if( (rc&0xff)==SQLITE_CORRUPT ){ raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); toggleSelectOrder(p->db); - shell_exec(p->db, sSelect.z, shell_callback, p, 0); + shell_exec(p, sSelect.z, 0); toggleSelectOrder(p->db); } p->zDestTable = savedDestTable; @@ -2666,123 +3335,234 @@ static int run_schema_dump_query( } /* -** Text of a help message +** Text of help messages. +** +** The help text for each individual command begins with a line that starts +** with ".". Subsequent lines are supplimental information. +** +** There must be two or more spaces between the end of the command and the +** start of the description of what that command does. */ -static char zHelp[] = -#ifndef SQLITE_OMIT_AUTHORIZATION - ".auth ON|OFF Show authorizer callbacks\n" +static const char *(azHelp[]) = { +#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) + ".archive ... Manage SQL archives", + " Each command must have exactly one of the following options:", + " -c, --create Create a new archive", + " -u, --update Update or add files to an existing archive", + " -t, --list List contents of archive", + " -x, --extract Extract files from archive", + " Optional arguments:", + " -v, --verbose Print each filename as it is processed", + " -f FILE, --file FILE Operate on archive FILE (default is current db)", + " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS", + " -C DIR, --directory DIR Change to directory DIR to read/extract files", + " -n, --dryrun Show the SQL that would have occurred", + " Examples:", + " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar", + " .ar -tf archive.sar # List members of archive.sar", + " .ar -xvf archive.sar # Verbosely extract files from archive.sar", + " See also:", + " http://sqlite.org/cli.html#sqlar_archive_support", #endif - ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" - ".bail on|off Stop after hitting an error. Default OFF\n" - ".binary on|off Turn binary output on or off. Default OFF\n" - ".cd DIRECTORY Change the working directory to DIRECTORY\n" - ".changes on|off Show number of rows changed by SQL\n" - ".check GLOB Fail if output since .testcase does not match\n" - ".clone NEWDB Clone data into NEWDB from the existing database\n" - ".databases List names and files of attached databases\n" - ".dbinfo ?DB? Show status information about the database\n" - ".dump ?TABLE? ... Dump the database in an SQL text format\n" - " If TABLE specified, only dump tables matching\n" - " LIKE pattern TABLE.\n" - ".echo on|off Turn command echo on or off\n" - ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" - ".exit Exit this program\n" +#ifndef SQLITE_OMIT_AUTHORIZATION + ".auth ON|OFF Show authorizer callbacks", +#endif + ".backup ?DB? FILE Backup DB (default \"main\") to FILE", + " --append Use the appendvfs", + ".bail on|off Stop after hitting an error. Default OFF", + ".binary on|off Turn binary output on or off. Default OFF", + ".cd DIRECTORY Change the working directory to DIRECTORY", + ".changes on|off Show number of rows changed by SQL", + ".check GLOB Fail if output since .testcase does not match", + ".clone NEWDB Clone data into NEWDB from the existing database", + ".databases List names and files of attached databases", + ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", + ".dbinfo ?DB? Show status information about the database", + ".dump ?TABLE? ... Render all database content as SQL", + " Options:", + " --preserve-rowids Include ROWID values in the output", + " --newlines Allow unescaped newline characters in output", + " TABLE is LIKE pattern for the tables to dump", + ".echo on|off Turn command echo on or off", + ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN", + ".excel Display the output of next command in a spreadsheet", + ".exit ?CODE? Exit this program with return-code CODE", + ".expert EXPERIMENTAL. Suggest indexes for specified queries", /* Because explain mode comes on automatically now, the ".explain" mode ** is removed from the help screen. It is still supported for legacy, however */ -/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/ - ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" - ".headers on|off Turn display of headers on or off\n" - ".help Show this message\n" - ".import FILE TABLE Import data from FILE into TABLE\n" +/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/ + ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", + ".headers on|off Turn display of headers on or off", + ".help ?-all? ?PATTERN? Show help text for PATTERN", + ".import FILE TABLE Import data from FILE into TABLE", #ifndef SQLITE_OMIT_TEST_CONTROL - ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n" + ".imposter INDEX TABLE Create imposter table TABLE on index INDEX", #endif - ".indexes ?TABLE? Show names of all indexes\n" - " If TABLE specified, only show indexes for tables\n" - " matching LIKE pattern TABLE.\n" + ".indexes ?TABLE? Show names of indexes", + " If TABLE is specified, only show indexes for", + " tables matching TABLE using the LIKE operator.", #ifdef SQLITE_ENABLE_IOTRACE - ".iotrace FILE Enable I/O diagnostic logging to FILE\n" + ".iotrace FILE Enable I/O diagnostic logging to FILE", #endif - ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" - ".lint OPTIONS Report potential schema issues. Options:\n" - " fkey-indexes Find missing foreign key indexes\n" + ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT", + ".lint OPTIONS Report potential schema issues.", + " Options:", + " fkey-indexes Find missing foreign key indexes", #ifndef SQLITE_OMIT_LOAD_EXTENSION - ".load FILE ?ENTRY? Load an extension library\n" + ".load FILE ?ENTRY? Load an extension library", #endif - ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" - ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" - " ascii Columns/rows delimited by 0x1F and 0x1E\n" - " csv Comma-separated values\n" - " column Left-aligned columns. (See .width)\n" - " html HTML
code\n" - " insert SQL insert statements for TABLE\n" - " line One value per line\n" - " list Values delimited by \"|\"\n" - " quote Escape answers as for SQL\n" - " tabs Tab-separated values\n" - " tcl TCL list elements\n" - ".nullvalue STRING Use STRING in place of NULL values\n" - ".once FILENAME Output for the next SQL command only to FILENAME\n" - ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n" - " The --new option starts with an empty file\n" - ".output ?FILENAME? Send output to FILENAME or stdout\n" - ".print STRING... Print literal STRING\n" - ".prompt MAIN CONTINUE Replace the standard prompts\n" - ".quit Exit this program\n" - ".read FILENAME Execute SQL in FILENAME\n" - ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" - ".save FILE Write in-memory database into FILE\n" - ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" - ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" - " Add --indent for pretty-printing\n" - ".selftest ?--init? Run tests defined in the SELFTEST table\n" - ".separator COL ?ROW? Change the column separator and optionally the row\n" - " separator for both the output mode and .import\n" + ".log FILE|off Turn logging on or off. FILE can be stderr/stdout", + ".mode MODE ?TABLE? Set output mode", + " MODE is one of:", + " ascii Columns/rows delimited by 0x1F and 0x1E", + " csv Comma-separated values", + " column Left-aligned columns. (See .width)", + " html HTML
code", + " insert SQL insert statements for TABLE", + " line One value per line", + " list Values delimited by \"|\"", + " quote Escape answers as for SQL", + " tabs Tab-separated values", + " tcl TCL list elements", + ".nullvalue STRING Use STRING in place of NULL values", + ".once (-e|-x|FILE) Output for the next SQL command only to FILE", + " If FILE begins with '|' then open as a pipe", + " Other options:", + " -e Invoke system text editor", + " -x Open in a spreadsheet", + ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", + " Options:", + " --append Use appendvfs to append database to the end of FILE", + " --new Initialize FILE to an empty database", + " --readonly Open FILE readonly", + " --zip FILE is a ZIP archive", + ".output ?FILE? Send output to FILE or stdout if FILE is omitted", + " If FILE begins with '|' then open it as a pipe.", + ".print STRING... Print literal STRING", + ".prompt MAIN CONTINUE Replace the standard prompts", + ".quit Exit this program", + ".read FILE Read input from FILE", + ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", + ".save FILE Write in-memory database into FILE", + ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off", + ".schema ?PATTERN? Show the CREATE statements matching PATTERN", + " Options:", + " --indent Try to pretty-print the schema", + ".selftest ?OPTIONS? Run tests defined in the SELFTEST table", + " Options:", + " --init Create a new SELFTEST table", + " -v Verbose output", + ".separator COL ?ROW? Change the column and row separators", #if defined(SQLITE_ENABLE_SESSION) - ".session CMD ... Create or control sessions\n" + ".session ?NAME? CMD ... Create or control sessions", + " Subcommands:", + " attach TABLE Attach TABLE", + " changeset FILE Write a changeset into FILE", + " close Close one session", + " enable ?BOOLEAN? Set or query the enable bit", + " filter GLOB... Reject tables matching GLOBs", + " indirect ?BOOLEAN? Mark or query the indirect status", + " isempty Query whether the session is empty", + " list List currently open session names", + " open DB NAME Open a new session on DB", + " patchset FILE Write a patchset into FILE", + " If ?NAME? is omitted, the first defined session is used.", #endif - ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n" - ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" - ".show Show the current values for various settings\n" - ".stats ?on|off? Show stats or turn stats on or off\n" - ".system CMD ARGS... Run CMD ARGS... in a system shell\n" - ".tables ?TABLE? List names of tables\n" - " If TABLE specified, only list tables matching\n" - " LIKE pattern TABLE.\n" - ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" - ".timeout MS Try opening locked tables for MS milliseconds\n" - ".timer on|off Turn SQL timer on or off\n" - ".trace FILE|off Output each SQL statement as it is run\n" - ".vfsinfo ?AUX? Information about the top-level VFS\n" - ".vfslist List all available VFSes\n" - ".vfsname ?AUX? Print the name of the VFS stack\n" - ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" - " Negative values right-justify\n" -; + ".sha3sum ... Compute a SHA3 hash of database content", + " Options:", + " --schema Also hash the sqlite_master table", + " --sha3-224 Use the sha3-224 algorithm", + " --sha3-256 Use the sha3-256 algorithm. This is the default.", + " --sha3-384 Use the sha3-384 algorithm", + " --sha3-512 Use the sha3-512 algorithm", + " Any other argument is a LIKE pattern for tables to hash", +#ifndef SQLITE_NOHAVE_SYSTEM + ".shell CMD ARGS... Run CMD ARGS... in a system shell", +#endif + ".show Show the current values for various settings", + ".stats ?on|off? Show stats or turn stats on or off", +#ifndef SQLITE_NOHAVE_SYSTEM + ".system CMD ARGS... Run CMD ARGS... in a system shell", +#endif + ".tables ?TABLE? List names of tables matching LIKE pattern TABLE", + ".testcase NAME Begin redirecting output to 'testcase-out.txt'", + ".timeout MS Try opening locked tables for MS milliseconds", + ".timer on|off Turn SQL timer on or off", + ".trace FILE|off Output each SQL statement as it is run", + ".vfsinfo ?AUX? Information about the top-level VFS", + ".vfslist List all available VFSes", + ".vfsname ?AUX? Print the name of the VFS stack", + ".width NUM1 NUM2 ... Set column widths for \"column\" mode", + " Negative values right-justify", +}; -#if defined(SQLITE_ENABLE_SESSION) /* -** Print help information for the ".sessions" command +** Output help text. +** +** zPattern describes the set of commands for which help text is provided. +** If zPattern is NULL, then show all commands, but only give a one-line +** description of each. +** +** Return the number of matches. */ -void session_help(ShellState *p){ - raw_printf(p->out, - ".session ?NAME? SUBCOMMAND ?ARGS...?\n" - "If ?NAME? is omitted, the first defined session is used.\n" - "Subcommands:\n" - " attach TABLE Attach TABLE\n" - " changeset FILE Write a changeset into FILE\n" - " close Close one session\n" - " enable ?BOOLEAN? Set or query the enable bit\n" - " filter GLOB... Reject tables matching GLOBs\n" - " indirect ?BOOLEAN? Mark or query the indirect status\n" - " isempty Query whether the session is empty\n" - " list List currently open session names\n" - " open DB NAME Open a new session on DB\n" - " patchset FILE Write a patchset into FILE\n" - ); +static int showHelp(FILE *out, const char *zPattern){ + int i, j; + int n = 0; + char *zPat; + if( zPattern==0 + || zPattern[0]=='0' + || strcmp(zPattern,"-a")==0 + || strcmp(zPattern,"-all")==0 + ){ + /* Show all commands, but only one line per command */ + if( zPattern==0 ) zPattern = ""; + for(i=0; idb==0 ){ - sqlite3_initialize(); - sqlite3_open(p->zDbFilename, &p->db); + if( p->openMode==SHELL_OPEN_UNSPEC ){ + if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){ + p->openMode = SHELL_OPEN_NORMAL; + }else{ + p->openMode = (u8)deduceDatabaseType(p->zDbFilename, + (openFlags & OPEN_DB_ZIPFILE)!=0); + } + } + switch( p->openMode ){ + case SHELL_OPEN_APPENDVFS: { + sqlite3_open_v2(p->zDbFilename, &p->db, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs"); + break; + } + case SHELL_OPEN_ZIPFILE: { + sqlite3_open(":memory:", &p->db); + break; + } + case SHELL_OPEN_READONLY: { + sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0); + break; + } + case SHELL_OPEN_UNSPEC: + case SHELL_OPEN_NORMAL: { + sqlite3_open(p->zDbFilename, &p->db); + break; + } + } globalDb = p->db; if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", p->zDbFilename, sqlite3_errmsg(p->db)); - if( keepAlive ) return; + if( openFlags & OPEN_DB_KEEPALIVE ) return; exit(1); } #ifndef SQLITE_OMIT_LOAD_EXTENSION @@ -2892,11 +3750,42 @@ static void open_db(ShellState *p, int keepAlive){ sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); sqlite3_completion_init(p->db, 0, 0); - sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0, +#ifdef SQLITE_HAVE_ZLIB + sqlite3_zipfile_init(p->db, 0, 0); + sqlite3_sqlar_init(p->db, 0, 0); +#endif + sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); + sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0, + shellModuleSchema, 0, 0); + sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p, + shellPutsFunc, 0, 0); +#ifndef SQLITE_NOHAVE_SYSTEM + sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0, + editFunc, 0, 0); + sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0, + editFunc, 0, 0); +#endif + if( p->openMode==SHELL_OPEN_ZIPFILE ){ + char *zSql = sqlite3_mprintf( + "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename); + sqlite3_exec(p->db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } } } +/* +** Attempt to close the databaes connection. Report errors. +*/ +void close_db(sqlite3 *db){ + int rc = sqlite3_close(db); + if( rc ){ + utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n", + rc, sqlite3_errmsg(db)); + } +} + #if HAVE_READLINE || HAVE_EDITLINE /* ** Readline completion callbacks @@ -2931,14 +3820,14 @@ static char **readline_completion(const char *zText, int iStart, int iEnd){ ** Linenoise completion callback */ static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){ - int nLine = (int)strlen(zLine); + int nLine = strlen30(zLine); int i, iStart; sqlite3_stmt *pStmt = 0; char *zSql; char zBuf[1000]; if( nLine>sizeof(zBuf)-30 ) return; - if( zLine[0]=='.' ) return; + if( zLine[0]=='.' || zLine[0]=='#') return; for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){} if( i==nLine-1 ) return; iStart = i+1; @@ -3021,63 +3910,6 @@ static void resolve_backslashes(char *z){ if( j='0' && c<='9' ) return c - '0'; - if( c>='a' && c<='f' ) return c - 'a' + 10; - if( c>='A' && c<='F' ) return c - 'A' + 10; - return -1; -} - -/* -** Interpret zArg as an integer value, possibly with suffixes. -*/ -static sqlite3_int64 integerValue(const char *zArg){ - sqlite3_int64 v = 0; - static const struct { char *zSuffix; int iMult; } aMult[] = { - { "KiB", 1024 }, - { "MiB", 1024*1024 }, - { "GiB", 1024*1024*1024 }, - { "KB", 1000 }, - { "MB", 1000000 }, - { "GB", 1000000000 }, - { "K", 1000 }, - { "M", 1000000 }, - { "G", 1000000000 }, - }; - int i; - int isNeg = 0; - if( zArg[0]=='-' ){ - isNeg = 1; - zArg++; - }else if( zArg[0]=='+' ){ - zArg++; - } - if( zArg[0]=='0' && zArg[1]=='x' ){ - int x; - zArg += 2; - while( (x = hexDigitValue(zArg[0]))>=0 ){ - v = (v<<4) + x; - zArg++; - } - }else{ - while( IsDigit(zArg[0]) ){ - v = v*10 + zArg[0] - '0'; - zArg++; - } - } - for(i=0; i0 && z[i-1]==';' ){ i--; } utf8_printf(f, "%.*s;\n", i, z); } return 0; } #endif -#endif /* ** A no-op routine that runs with the ".breakpoint" doc-command. This is @@ -3197,10 +4027,7 @@ static void import_append_char(ImportCtx *p, int c){ if( p->n+1>=p->nAlloc ){ p->nAlloc += p->nAlloc + 100; p->z = sqlite3_realloc64(p->z, p->nAlloc); - if( p->z==0 ){ - raw_printf(stderr, "out of memory\n"); - exit(1); - } + if( p->z==0 ) shell_out_of_memory(); } p->z[p->n++] = (char)c; } @@ -3346,7 +4173,7 @@ static void tryToCloneData( char *zInsert = 0; int rc; int i, j, n; - int nTable = (int)strlen(zTable); + int nTable = strlen30(zTable); int k = 0; int cnt = 0; const int spinRate = 10000; @@ -3361,13 +4188,10 @@ static void tryToCloneData( } n = sqlite3_column_count(pQuery); zInsert = sqlite3_malloc64(200 + nTable + n*3); - if( zInsert==0 ){ - raw_printf(stderr, "out of memory\n"); - goto end_data_xfer; - } + if( zInsert==0 ) shell_out_of_memory(); sqlite3_snprintf(200+nTable,zInsert, "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); - i = (int)strlen(zInsert); + i = strlen30(zInsert); for(j=1; jdb, "PRAGMA writable_schema=OFF;", 0, 0, 0); } - sqlite3_close(newDb); + close_db(newDb); } /* -** Change the output file back to stdout +** Change the output file back to stdout. +** +** If the p->doXdgOpen flag is set, that means the output was being +** redirected to a temporary file named by p->zTempFile. In that case, +** launch start/open/xdg-open on that temporary file. */ static void output_reset(ShellState *p){ if( p->outfile[0]=='|' ){ @@ -3555,6 +4383,26 @@ static void output_reset(ShellState *p){ #endif }else{ output_file_close(p->out); +#ifndef SQLITE_NOHAVE_SYSTEM + if( p->doXdgOpen ){ + const char *zXdgOpenCmd = +#if defined(_WIN32) + "start"; +#elif defined(__APPLE__) + "open"; +#else + "xdg-open"; +#endif + char *zCmd; + zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile); + if( system(zCmd) ){ + utf8_printf(stderr, "Failed: [%s]\n", zCmd); + } + sqlite3_free(zCmd); + outputModePop(p); + p->doXdgOpen = 0; + } +#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ } p->outfile[0] = 0; p->out = stdout; @@ -3616,20 +4464,25 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ { "schema size:", "SELECT total(length(sql)) FROM %s" }, }; - sqlite3_file *pFile = 0; int i; + unsigned iDataVersion; char *zSchemaTab; char *zDb = nArg>=2 ? azArg[1] : "main"; + sqlite3_stmt *pStmt = 0; unsigned char aHdr[100]; open_db(p, 0); if( p->db==0 ) return 1; - sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); - if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ - return 1; - } - i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); - if( i!=SQLITE_OK ){ + sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1", + -1, &pStmt, 0); + sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC); + if( sqlite3_step(pStmt)==SQLITE_ROW + && sqlite3_column_bytes(pStmt,0)>100 + ){ + memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100); + sqlite3_finalize(pStmt); + }else{ raw_printf(stderr, "unable to read database header\n"); + sqlite3_finalize(pStmt); return 1; } i = get2byteInt(aHdr+16); @@ -3665,6 +4518,8 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val); } sqlite3_free(zSchemaTab); + sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion); + utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion); return 0; } @@ -3677,14 +4532,6 @@ static int shellDatabaseError(sqlite3 *db){ return 1; } -/* -** Print an out-of-memory message to stderr and return 1. -*/ -static int shellNomemError(void){ - raw_printf(stderr, "Error: out of memory\n"); - return 1; -} - /* ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE ** if they match and FALSE (0) if they do not match. @@ -3809,6 +4656,41 @@ int shellDeleteFile(const char *zFilename){ return rc; } +/* +** Try to delete the temporary file (if there is one) and free the +** memory used to hold the name of the temp file. +*/ +static void clearTempFile(ShellState *p){ + if( p->zTempFile==0 ) return; + if( p->doXdgOpen ) return; + if( shellDeleteFile(p->zTempFile) ) return; + sqlite3_free(p->zTempFile); + p->zTempFile = 0; +} + +/* +** Create a new temp file name with the given suffix. +*/ +static void newTempFile(ShellState *p, const char *zSuffix){ + clearTempFile(p); + sqlite3_free(p->zTempFile); + p->zTempFile = 0; + if( p->db ){ + sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile); + } + if( p->zTempFile==0 ){ + sqlite3_uint64 r; + sqlite3_randomness(sizeof(r), &r); + p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix); + }else{ + p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix); + } + if( p->zTempFile==0 ){ + raw_printf(stderr, "out of memory\n"); + exit(1); + } +} + /* ** The implementation of SQL scalar function fkey_collate_clause(), used @@ -3886,10 +4768,10 @@ static int lintFkeyIndexes( ** ** 0. The text of an SQL statement similar to: ** - ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?" + ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?" ** - ** This is the same SELECT that the foreign keys implementation needs - ** to run internally on child tables. If there is an index that can + ** This SELECT is similar to the one that the foreign keys implementation + ** needs to run internally on child tables. If there is an index that can ** be used to optimize this query, then it can also be used by the FK ** implementation to optimize DELETE or UPDATE statements on the parent ** table. @@ -3917,7 +4799,7 @@ static int lintFkeyIndexes( */ const char *zSql = "SELECT " - " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '" + " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '" " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " " || fkey_collate_clause(" " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" @@ -3945,7 +4827,7 @@ static int lintFkeyIndexes( const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)"; for(i=2; i1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ bVerbose = 1; } @@ -4048,7 +4930,7 @@ static int lintDotCommand( int nArg /* Number of entries in azArg[] */ ){ int n; - n = (nArg>=2 ? (int)strlen(azArg[1]) : 0); + n = (nArg>=2 ? strlen30(azArg[1]) : 0); if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; return lintFkeyIndexes(pState, azArg, nArg); @@ -4059,6 +4941,738 @@ static int lintDotCommand( return SQLITE_ERROR; } +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) +/********************************************************************************* +** The ".archive" or ".ar" command. +*/ +static void shellPrepare( + sqlite3 *db, + int *pRc, + const char *zSql, + sqlite3_stmt **ppStmt +){ + *ppStmt = 0; + if( *pRc==SQLITE_OK ){ + int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); + if( rc!=SQLITE_OK ){ + raw_printf(stderr, "sql error: %s (%d)\n", + sqlite3_errmsg(db), sqlite3_errcode(db) + ); + *pRc = rc; + } + } +} + +static void shellPreparePrintf( + sqlite3 *db, + int *pRc, + sqlite3_stmt **ppStmt, + const char *zFmt, + ... +){ + *ppStmt = 0; + if( *pRc==SQLITE_OK ){ + va_list ap; + char *z; + va_start(ap, zFmt); + z = sqlite3_vmprintf(zFmt, ap); + if( z==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + shellPrepare(db, pRc, z, ppStmt); + sqlite3_free(z); + } + } +} + +static void shellFinalize( + int *pRc, + sqlite3_stmt *pStmt +){ + if( pStmt ){ + sqlite3 *db = sqlite3_db_handle(pStmt); + int rc = sqlite3_finalize(pStmt); + if( *pRc==SQLITE_OK ){ + if( rc!=SQLITE_OK ){ + raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); + } + *pRc = rc; + } + } +} + +static void shellReset( + int *pRc, + sqlite3_stmt *pStmt +){ + int rc = sqlite3_reset(pStmt); + if( *pRc==SQLITE_OK ){ + if( rc!=SQLITE_OK ){ + sqlite3 *db = sqlite3_db_handle(pStmt); + raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); + } + *pRc = rc; + } +} +/* +** Structure representing a single ".ar" command. +*/ +typedef struct ArCommand ArCommand; +struct ArCommand { + u8 eCmd; /* An AR_CMD_* value */ + u8 bVerbose; /* True if --verbose */ + u8 bZip; /* True if the archive is a ZIP */ + u8 bDryRun; /* True if --dry-run */ + u8 bAppend; /* True if --append */ + u8 fromCmdLine; /* Run from -A instead of .archive */ + int nArg; /* Number of command arguments */ + char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */ + const char *zFile; /* --file argument, or NULL */ + const char *zDir; /* --directory argument, or NULL */ + char **azArg; /* Array of command arguments */ + ShellState *p; /* Shell state */ + sqlite3 *db; /* Database containing the archive */ +}; + +/* +** Print a usage message for the .ar command to stderr and return SQLITE_ERROR. +*/ +static int arUsage(FILE *f){ + showHelp(f,"archive"); + return SQLITE_ERROR; +} + +/* +** Print an error message for the .ar command to stderr and return +** SQLITE_ERROR. +*/ +static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){ + va_list ap; + char *z; + va_start(ap, zFmt); + z = sqlite3_vmprintf(zFmt, ap); + va_end(ap); + utf8_printf(stderr, "Error: %s\n", z); + if( pAr->fromCmdLine ){ + utf8_printf(stderr, "Use \"-A\" for more help\n"); + }else{ + utf8_printf(stderr, "Use \".archive --help\" for more help\n"); + } + sqlite3_free(z); + return SQLITE_ERROR; +} + +/* +** Values for ArCommand.eCmd. +*/ +#define AR_CMD_CREATE 1 +#define AR_CMD_EXTRACT 2 +#define AR_CMD_LIST 3 +#define AR_CMD_UPDATE 4 +#define AR_CMD_HELP 5 + +/* +** Other (non-command) switches. +*/ +#define AR_SWITCH_VERBOSE 6 +#define AR_SWITCH_FILE 7 +#define AR_SWITCH_DIRECTORY 8 +#define AR_SWITCH_APPEND 9 +#define AR_SWITCH_DRYRUN 10 + +static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){ + switch( eSwitch ){ + case AR_CMD_CREATE: + case AR_CMD_EXTRACT: + case AR_CMD_LIST: + case AR_CMD_UPDATE: + case AR_CMD_HELP: + if( pAr->eCmd ){ + return arErrorMsg(pAr, "multiple command options"); + } + pAr->eCmd = eSwitch; + break; + + case AR_SWITCH_DRYRUN: + pAr->bDryRun = 1; + break; + case AR_SWITCH_VERBOSE: + pAr->bVerbose = 1; + break; + case AR_SWITCH_APPEND: + pAr->bAppend = 1; + /* Fall thru into --file */ + case AR_SWITCH_FILE: + pAr->zFile = zArg; + break; + case AR_SWITCH_DIRECTORY: + pAr->zDir = zArg; + break; + } + + return SQLITE_OK; +} + +/* +** Parse the command line for an ".ar" command. The results are written into +** structure (*pAr). SQLITE_OK is returned if the command line is parsed +** successfully, otherwise an error message is written to stderr and +** SQLITE_ERROR returned. +*/ +static int arParseCommand( + char **azArg, /* Array of arguments passed to dot command */ + int nArg, /* Number of entries in azArg[] */ + ArCommand *pAr /* Populate this object */ +){ + struct ArSwitch { + const char *zLong; + char cShort; + u8 eSwitch; + u8 bArg; + } aSwitch[] = { + { "create", 'c', AR_CMD_CREATE, 0 }, + { "extract", 'x', AR_CMD_EXTRACT, 0 }, + { "list", 't', AR_CMD_LIST, 0 }, + { "update", 'u', AR_CMD_UPDATE, 0 }, + { "help", 'h', AR_CMD_HELP, 0 }, + { "verbose", 'v', AR_SWITCH_VERBOSE, 0 }, + { "file", 'f', AR_SWITCH_FILE, 1 }, + { "append", 'a', AR_SWITCH_APPEND, 1 }, + { "directory", 'C', AR_SWITCH_DIRECTORY, 1 }, + { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 }, + }; + int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch); + struct ArSwitch *pEnd = &aSwitch[nSwitch]; + + if( nArg<=1 ){ + utf8_printf(stderr, "Wrong number of arguments. Usage:\n"); + return arUsage(stderr); + }else{ + char *z = azArg[1]; + if( z[0]!='-' ){ + /* Traditional style [tar] invocation */ + int i; + int iArg = 2; + for(i=0; z[i]; i++){ + const char *zArg = 0; + struct ArSwitch *pOpt; + for(pOpt=&aSwitch[0]; pOptcShort ) break; + } + if( pOpt==pEnd ){ + return arErrorMsg(pAr, "unrecognized option: %c", z[i]); + } + if( pOpt->bArg ){ + if( iArg>=nArg ){ + return arErrorMsg(pAr, "option requires an argument: %c",z[i]); + } + zArg = azArg[iArg++]; + } + if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; + } + pAr->nArg = nArg-iArg; + if( pAr->nArg>0 ){ + pAr->azArg = &azArg[iArg]; + } + }else{ + /* Non-traditional invocation */ + int iArg; + for(iArg=1; iArgazArg = &azArg[iArg]; + pAr->nArg = nArg-iArg; + break; + } + n = strlen30(z); + + if( z[1]!='-' ){ + int i; + /* One or more short options */ + for(i=1; icShort ) break; + } + if( pOpt==pEnd ){ + return arErrorMsg(pAr, "unrecognized option: %c", z[i]); + } + if( pOpt->bArg ){ + if( i<(n-1) ){ + zArg = &z[i+1]; + i = n; + }else{ + if( iArg>=(nArg-1) ){ + return arErrorMsg(pAr, "option requires an argument: %c",z[i]); + } + zArg = azArg[++iArg]; + } + } + if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; + } + }else if( z[2]=='\0' ){ + /* A -- option, indicating that all remaining command line words + ** are command arguments. */ + pAr->azArg = &azArg[iArg+1]; + pAr->nArg = nArg-iArg-1; + break; + }else{ + /* A long option */ + const char *zArg = 0; /* Argument for option, if any */ + struct ArSwitch *pMatch = 0; /* Matching option */ + struct ArSwitch *pOpt; /* Iterator */ + for(pOpt=&aSwitch[0]; pOptzLong; + if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){ + if( pMatch ){ + return arErrorMsg(pAr, "ambiguous option: %s",z); + }else{ + pMatch = pOpt; + } + } + } + + if( pMatch==0 ){ + return arErrorMsg(pAr, "unrecognized option: %s", z); + } + if( pMatch->bArg ){ + if( iArg>=(nArg-1) ){ + return arErrorMsg(pAr, "option requires an argument: %s", z); + } + zArg = azArg[++iArg]; + } + if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR; + } + } + } + } + + return SQLITE_OK; +} + +/* +** This function assumes that all arguments within the ArCommand.azArg[] +** array refer to archive members, as for the --extract or --list commands. +** It checks that each of them are present. If any specified file is not +** present in the archive, an error is printed to stderr and an error +** code returned. Otherwise, if all specified arguments are present in +** the archive, SQLITE_OK is returned. +** +** This function strips any trailing '/' characters from each argument. +** This is consistent with the way the [tar] command seems to work on +** Linux. +*/ +static int arCheckEntries(ArCommand *pAr){ + int rc = SQLITE_OK; + if( pAr->nArg ){ + int i, j; + sqlite3_stmt *pTest = 0; + + shellPreparePrintf(pAr->db, &rc, &pTest, + "SELECT name FROM %s WHERE name=$name", + pAr->zSrcTable + ); + j = sqlite3_bind_parameter_index(pTest, "$name"); + for(i=0; inArg && rc==SQLITE_OK; i++){ + char *z = pAr->azArg[i]; + int n = strlen30(z); + int bOk = 0; + while( n>0 && z[n-1]=='/' ) n--; + z[n] = '\0'; + sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pTest) ){ + bOk = 1; + } + shellReset(&rc, pTest); + if( rc==SQLITE_OK && bOk==0 ){ + utf8_printf(stderr, "not found in archive: %s\n", z); + rc = SQLITE_ERROR; + } + } + shellFinalize(&rc, pTest); + } + return rc; +} + +/* +** Format a WHERE clause that can be used against the "sqlar" table to +** identify all archive members that match the command arguments held +** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning. +** The caller is responsible for eventually calling sqlite3_free() on +** any non-NULL (*pzWhere) value. +*/ +static void arWhereClause( + int *pRc, + ArCommand *pAr, + char **pzWhere /* OUT: New WHERE clause */ +){ + char *zWhere = 0; + if( *pRc==SQLITE_OK ){ + if( pAr->nArg==0 ){ + zWhere = sqlite3_mprintf("1"); + }else{ + int i; + const char *zSep = ""; + for(i=0; inArg; i++){ + const char *z = pAr->azArg[i]; + zWhere = sqlite3_mprintf( + "%z%s name = '%q' OR substr(name,1,%d) = '%q/'", + zWhere, zSep, z, strlen30(z)+1, z + ); + if( zWhere==0 ){ + *pRc = SQLITE_NOMEM; + break; + } + zSep = " OR "; + } + } + } + *pzWhere = zWhere; +} + +/* +** Implementation of .ar "lisT" command. +*/ +static int arListCommand(ArCommand *pAr){ + const char *zSql = "SELECT %s FROM %s WHERE %s"; + const char *azCols[] = { + "name", + "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name" + }; + + char *zWhere = 0; + sqlite3_stmt *pSql = 0; + int rc; + + rc = arCheckEntries(pAr); + arWhereClause(&rc, pAr, &zWhere); + + shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], + pAr->zSrcTable, zWhere); + if( pAr->bDryRun ){ + utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql)); + }else{ + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ + if( pAr->bVerbose ){ + utf8_printf(pAr->p->out, "%s % 10d %s %s\n", + sqlite3_column_text(pSql, 0), + sqlite3_column_int(pSql, 1), + sqlite3_column_text(pSql, 2), + sqlite3_column_text(pSql, 3) + ); + }else{ + utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0)); + } + } + } + shellFinalize(&rc, pSql); + sqlite3_free(zWhere); + return rc; +} + + +/* +** Implementation of .ar "eXtract" command. +*/ +static int arExtractCommand(ArCommand *pAr){ + const char *zSql1 = + "SELECT " + " ($dir || name)," + " writefile(($dir || name), %s, mode, mtime) " + "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)" + " AND name NOT GLOB '*..[/\\]*'"; + + const char *azExtraArg[] = { + "sqlar_uncompress(data, sz)", + "data" + }; + + sqlite3_stmt *pSql = 0; + int rc = SQLITE_OK; + char *zDir = 0; + char *zWhere = 0; + int i, j; + + /* If arguments are specified, check that they actually exist within + ** the archive before proceeding. And formulate a WHERE clause to + ** match them. */ + rc = arCheckEntries(pAr); + arWhereClause(&rc, pAr, &zWhere); + + if( rc==SQLITE_OK ){ + if( pAr->zDir ){ + zDir = sqlite3_mprintf("%s/", pAr->zDir); + }else{ + zDir = sqlite3_mprintf(""); + } + if( zDir==0 ) rc = SQLITE_NOMEM; + } + + shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, + azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere + ); + + if( rc==SQLITE_OK ){ + j = sqlite3_bind_parameter_index(pSql, "$dir"); + sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC); + + /* Run the SELECT statement twice. The first time, writefile() is called + ** for all archive members that should be extracted. The second time, + ** only for the directories. This is because the timestamps for + ** extracted directories must be reset after they are populated (as + ** populating them changes the timestamp). */ + for(i=0; i<2; i++){ + j = sqlite3_bind_parameter_index(pSql, "$dirOnly"); + sqlite3_bind_int(pSql, j, i); + if( pAr->bDryRun ){ + utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql)); + }else{ + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ + if( i==0 && pAr->bVerbose ){ + utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0)); + } + } + } + shellReset(&rc, pSql); + } + shellFinalize(&rc, pSql); + } + + sqlite3_free(zDir); + sqlite3_free(zWhere); + return rc; +} + +/* +** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out. +*/ +static int arExecSql(ArCommand *pAr, const char *zSql){ + int rc; + if( pAr->bDryRun ){ + utf8_printf(pAr->p->out, "%s\n", zSql); + rc = SQLITE_OK; + }else{ + char *zErr = 0; + rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); + if( zErr ){ + utf8_printf(stdout, "ERROR: %s\n", zErr); + sqlite3_free(zErr); + } + } + return rc; +} + + +/* +** Implementation of .ar "create" and "update" commands. +** +** Create the "sqlar" table in the database if it does not already exist. +** Then add each file in the azFile[] array to the archive. Directories +** are added recursively. If argument bVerbose is non-zero, a message is +** printed on stdout for each file archived. +** +** The create command is the same as update, except that it drops +** any existing "sqlar" table before beginning. +*/ +static int arCreateOrUpdateCommand( + ArCommand *pAr, /* Command arguments and options */ + int bUpdate /* true for a --create. false for --update */ +){ + const char *zCreate = + "CREATE TABLE IF NOT EXISTS sqlar(\n" + " name TEXT PRIMARY KEY, -- name of the file\n" + " mode INT, -- access permissions\n" + " mtime INT, -- last modification time\n" + " sz INT, -- original file size\n" + " data BLOB -- compressed content\n" + ")"; + const char *zDrop = "DROP TABLE IF EXISTS sqlar"; + const char *zInsertFmt[2] = { + "REPLACE INTO %s(name,mode,mtime,sz,data)\n" + " SELECT\n" + " %s,\n" + " mode,\n" + " mtime,\n" + " CASE substr(lsmode(mode),1,1)\n" + " WHEN '-' THEN length(data)\n" + " WHEN 'd' THEN 0\n" + " ELSE -1 END,\n" + " sqlar_compress(data)\n" + " FROM fsdir(%Q,%Q)\n" + " WHERE lsmode(mode) NOT LIKE '?%%';", + "REPLACE INTO %s(name,mode,mtime,data)\n" + " SELECT\n" + " %s,\n" + " mode,\n" + " mtime,\n" + " data\n" + " FROM fsdir(%Q,%Q)\n" + " WHERE lsmode(mode) NOT LIKE '?%%';" + }; + int i; /* For iterating through azFile[] */ + int rc; /* Return code */ + const char *zTab = 0; /* SQL table into which to insert */ + char *zSql; + char zTemp[50]; + + arExecSql(pAr, "PRAGMA page_size=512"); + rc = arExecSql(pAr, "SAVEPOINT ar;"); + if( rc!=SQLITE_OK ) return rc; + zTemp[0] = 0; + if( pAr->bZip ){ + /* Initialize the zipfile virtual table, if necessary */ + if( pAr->zFile ){ + sqlite3_uint64 r; + sqlite3_randomness(sizeof(r),&r); + sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r); + zTab = zTemp; + zSql = sqlite3_mprintf( + "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)", + zTab, pAr->zFile + ); + rc = arExecSql(pAr, zSql); + sqlite3_free(zSql); + }else{ + zTab = "zip"; + } + }else{ + /* Initialize the table for an SQLAR */ + zTab = "sqlar"; + if( bUpdate==0 ){ + rc = arExecSql(pAr, zDrop); + if( rc!=SQLITE_OK ) goto end_ar_transaction; + } + rc = arExecSql(pAr, zCreate); + } + for(i=0; inArg && rc==SQLITE_OK; i++){ + char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab, + pAr->bVerbose ? "shell_putsnl(name)" : "name", + pAr->azArg[i], pAr->zDir); + rc = arExecSql(pAr, zSql2); + sqlite3_free(zSql2); + } +end_ar_transaction: + if( rc!=SQLITE_OK ){ + arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;"); + }else{ + rc = arExecSql(pAr, "RELEASE ar;"); + if( pAr->bZip && pAr->zFile ){ + zSql = sqlite3_mprintf("DROP TABLE %s", zTemp); + arExecSql(pAr, zSql); + sqlite3_free(zSql); + } + } + return rc; +} + +/* +** Implementation of ".ar" dot command. +*/ +static int arDotCommand( + ShellState *pState, /* Current shell tool state */ + int fromCmdLine, /* True if -A command-line option, not .ar cmd */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ +){ + ArCommand cmd; + int rc; + memset(&cmd, 0, sizeof(cmd)); + cmd.fromCmdLine = fromCmdLine; + rc = arParseCommand(azArg, nArg, &cmd); + if( rc==SQLITE_OK ){ + int eDbType = SHELL_OPEN_UNSPEC; + cmd.p = pState; + cmd.db = pState->db; + if( cmd.zFile ){ + eDbType = deduceDatabaseType(cmd.zFile, 1); + }else{ + eDbType = pState->openMode; + } + if( eDbType==SHELL_OPEN_ZIPFILE ){ + if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){ + if( cmd.zFile==0 ){ + cmd.zSrcTable = sqlite3_mprintf("zip"); + }else{ + cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile); + } + } + cmd.bZip = 1; + }else if( cmd.zFile ){ + int flags; + if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS; + if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){ + flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; + }else{ + flags = SQLITE_OPEN_READONLY; + } + cmd.db = 0; + if( cmd.bDryRun ){ + utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile, + eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : ""); + } + rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, + eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); + if( rc!=SQLITE_OK ){ + utf8_printf(stderr, "cannot open file: %s (%s)\n", + cmd.zFile, sqlite3_errmsg(cmd.db) + ); + goto end_ar_command; + } + sqlite3_fileio_init(cmd.db, 0, 0); + sqlite3_sqlar_init(cmd.db, 0, 0); + sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p, + shellPutsFunc, 0, 0); + + } + if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){ + if( cmd.eCmd!=AR_CMD_CREATE + && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0) + ){ + utf8_printf(stderr, "database does not contain an 'sqlar' table\n"); + rc = SQLITE_ERROR; + goto end_ar_command; + } + cmd.zSrcTable = sqlite3_mprintf("sqlar"); + } + + switch( cmd.eCmd ){ + case AR_CMD_CREATE: + rc = arCreateOrUpdateCommand(&cmd, 0); + break; + + case AR_CMD_EXTRACT: + rc = arExtractCommand(&cmd); + break; + + case AR_CMD_LIST: + rc = arListCommand(&cmd); + break; + + case AR_CMD_HELP: + arUsage(pState->out); + break; + + default: + assert( cmd.eCmd==AR_CMD_UPDATE ); + rc = arCreateOrUpdateCommand(&cmd, 1); + break; + } + } +end_ar_command: + if( cmd.db!=pState->db ){ + close_db(cmd.db); + } + sqlite3_free(cmd.zSrcTable); + + return rc; +} +/* End of the ".archive" or ".ar" command logic +**********************************************************************************/ +#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ + /* ** If an input line begins with "." then invoke this routine to @@ -4073,6 +5687,12 @@ static int do_meta_command(char *zLine, ShellState *p){ int rc = 0; char *azArg[50]; +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( p->expert.pExpert ){ + expertFinish(p, 1, 0); + } +#endif + /* Parse the input line into tokens. */ while( zLine[h] && nArg=3 && strncmp(azArg[0], "backup", n)==0) || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) ){ @@ -4127,11 +5755,14 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3 *pDest; sqlite3_backup *pBackup; int j; + const char *zVfs = 0; for(j=1; jdb, zDb); if( pBackup==0 ){ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - sqlite3_close(pDest); + close_db(pDest); return 1; } while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} @@ -4172,7 +5804,7 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); rc = 1; } - sqlite3_close(pDest); + close_db(pDest); }else if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ @@ -4249,7 +5881,7 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(stderr, "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", p->zTestcase, azArg[1], zRes); - rc = 2; + rc = 1; }else{ utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); p->nCheck++; @@ -4284,7 +5916,38 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ + if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){ + static const struct DbConfigChoices { + const char *zName; + int op; + } aDbConfig[] = { + { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, + { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, + { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, + { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, + { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, + { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, + { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, + { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, + }; + int ii, v; + open_db(p, 0); + for(ii=0; ii1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue; + if( nArg>=3 ){ + sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); + } + sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); + utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); + if( nArg>1 ) break; + } + if( nArg>1 && ii==ArraySize(aDbConfig) ){ + utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]); + utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n"); + } + }else + + if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){ rc = shell_dbinfo_command(p, nArg, azArg); }else @@ -4292,7 +5955,8 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zLike = 0; int i; int savedShowHeader = p->showHeader; - ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines); + int savedShellFlags = p->shellFlgs; + ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo); for(i=1; idb, "RELEASE dump;", 0, 0, 0); raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); p->showHeader = savedShowHeader; + p->shellFlgs = savedShellFlags; }else if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ @@ -4387,13 +6052,19 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ if( nArg==2 ){ + p->autoEQPtest = 0; if( strcmp(azArg[1],"full")==0 ){ - p->autoEQP = 2; + p->autoEQP = AUTOEQP_full; + }else if( strcmp(azArg[1],"trigger")==0 ){ + p->autoEQP = AUTOEQP_trigger; + }else if( strcmp(azArg[1],"test")==0 ){ + p->autoEQP = AUTOEQP_on; + p->autoEQPtest = 1; }else{ - p->autoEQP = booleanValue(azArg[1]); + p->autoEQP = (u8)booleanValue(azArg[1]); } }else{ - raw_printf(stderr, "Usage: .eqp on|off|full\n"); + raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n"); rc = 1; } }else @@ -4427,6 +6098,13 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){ + open_db(p, 0); + expertDotCommand(p, azArg, nArg); + }else +#endif + if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ ShellState data; char *zErrMsg = 0; @@ -4470,14 +6148,11 @@ static int do_meta_command(char *zLine, ShellState *p){ callback, &data, &zErrMsg); data.cMode = data.mode = MODE_Insert; data.zDestTable = "sqlite_stat1"; - shell_exec(p->db, "SELECT * FROM sqlite_stat1", - shell_callback, &data,&zErrMsg); + shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg); data.zDestTable = "sqlite_stat3"; - shell_exec(p->db, "SELECT * FROM sqlite_stat3", - shell_callback, &data,&zErrMsg); + shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg); data.zDestTable = "sqlite_stat4"; - shell_exec(p->db, "SELECT * FROM sqlite_stat4", - shell_callback, &data, &zErrMsg); + shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg); raw_printf(p->out, "ANALYZE sqlite_master;\n"); } }else @@ -4492,7 +6167,14 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - utf8_printf(p->out, "%s", zHelp); + if( nArg>=2 ){ + int n = showHelp(p->out, azArg[1]); + if( n==0 ){ + utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]); + } + }else{ + showHelp(p->out, 0); + } }else if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ @@ -4575,9 +6257,8 @@ static int do_meta_command(char *zLine, ShellState *p){ sCtx.cRowSep = p->rowSeparator[0]; zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); xCloser(sCtx.in); - return 1; + shell_out_of_memory(); } nByte = strlen30(zSql); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); @@ -4622,9 +6303,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCol==0 ) return 0; /* no columns, no error */ zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); xCloser(sCtx.in); - return 1; + shell_out_of_memory(); } sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); j = strlen30(zSql); @@ -4700,12 +6380,17 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_stmt *pStmt; int tnum = 0; int i; - if( nArg!=3 ){ - utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"); + if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ + utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n" + " .imposter off\n"); rc = 1; goto meta_command_exit; } open_db(p, 0); + if( nArg==2 ){ + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1); + goto meta_command_exit; + } zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master" " WHERE name='%q' AND type='index'", azArg[1]); sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); @@ -4881,13 +6566,13 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ const char *zFile = azArg[1]; output_file_close(p->pLog); - p->pLog = output_file_open(zFile); + p->pLog = output_file_open(zFile, 0); } }else if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ const char *zMode = nArg>=2 ? azArg[1] : ""; - int n2 = (int)strlen(zMode); + int n2 = strlen30(zMode); int c2 = zMode[0]; if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ p->mode = MODE_Line; @@ -4947,16 +6632,25 @@ static int do_meta_command(char *zLine, ShellState *p){ int newFlag = 0; /* True to delete file before opening */ /* Close the existing database */ session_close_all(p); - sqlite3_close(p->db); + close_db(p->db); p->db = 0; p->zDbFilename = 0; sqlite3_free(p->zFreeOnClose); p->zFreeOnClose = 0; + p->openMode = SHELL_OPEN_UNSPEC; /* Check for command-line arguments */ for(iName=1; iNameopenMode = SHELL_OPEN_ZIPFILE; +#endif + }else if( optionMatch(z, "append") ){ + p->openMode = SHELL_OPEN_APPENDVFS; + }else if( optionMatch(z, "readonly") ){ + p->openMode = SHELL_OPEN_READONLY; }else if( z[0]=='-' ){ utf8_printf(stderr, "unknown option: %s\n", z); rc = 1; @@ -4968,7 +6662,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zNewFilename ){ if( newFlag ) shellDeleteFile(zNewFilename); p->zDbFilename = zNewFilename; - open_db(p, 1); + open_db(p, OPEN_DB_KEEPALIVE); if( p->db==0 ){ utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); sqlite3_free(zNewFilename); @@ -4983,18 +6677,27 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - if( c=='o' - && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0) + if( (c=='o' + && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0)) + || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0) ){ const char *zFile = nArg>=2 ? azArg[1] : "stdout"; + int bTxtMode = 0; + if( azArg[0][0]=='e' ){ + /* Transform the ".excel" command into ".once -x" */ + nArg = 2; + azArg[0] = "once"; + zFile = azArg[1] = "-x"; + n = 4; + } if( nArg>2 ){ - utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]); + utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]); rc = 1; goto meta_command_exit; } if( n>1 && strncmp(azArg[0], "once", n)==0 ){ if( nArg<2 ){ - raw_printf(stderr, "Usage: .once FILE\n"); + raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n"); rc = 1; goto meta_command_exit; } @@ -5003,6 +6706,23 @@ static int do_meta_command(char *zLine, ShellState *p){ p->outCount = 0; } output_reset(p); + if( zFile[0]=='-' && zFile[1]=='-' ) zFile++; +#ifndef SQLITE_NOHAVE_SYSTEM + if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){ + p->doXdgOpen = 1; + outputModePush(p); + if( zFile[1]=='x' ){ + newTempFile(p, "csv"); + p->mode = MODE_Csv; + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); + }else{ + newTempFile(p, "txt"); + bTxtMode = 1; + } + zFile = p->zTempFile; + } +#endif /* SQLITE_NOHAVE_SYSTEM */ if( zFile[0]=='|' ){ #ifdef SQLITE_OMIT_POPEN raw_printf(stderr, "Error: pipes are not supported in this OS\n"); @@ -5019,7 +6739,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } #endif }else{ - p->out = output_file_open(zFile); + p->out = output_file_open(zFile, bTxtMode); if( p->out==0 ){ if( strcmp(zFile,"off")!=0 ){ utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile); @@ -5092,14 +6812,14 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_open(zSrcFile, &pSrc); if( rc!=SQLITE_OK ){ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); - sqlite3_close(pSrc); + close_db(pSrc); return 1; } open_db(p, 0); pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); if( pBackup==0 ){ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - sqlite3_close(pSrc); + close_db(pSrc); return 1; } while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK @@ -5119,13 +6839,12 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); rc = 1; } - sqlite3_close(pSrc); + close_db(pSrc); }else - if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){ if( nArg==2 ){ - p->scanstatsOn = booleanValue(azArg[1]); + p->scanstatsOn = (u8)booleanValue(azArg[1]); #ifndef SQLITE_ENABLE_STMT_SCANSTATUS raw_printf(stderr, "Warning: .scanstats not available in this build.\n"); #endif @@ -5139,59 +6858,48 @@ static int do_meta_command(char *zLine, ShellState *p){ ShellText sSelect; ShellState data; char *zErrMsg = 0; - const char *zDiv = 0; + const char *zDiv = "("; + const char *zName = 0; int iSchema = 0; + int bDebug = 0; + int ii; open_db(p, 0); memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.cMode = data.mode = MODE_Semi; initText(&sSelect); - if( nArg>=2 && optionMatch(azArg[1], "indent") ){ - data.cMode = data.mode = MODE_Pretty; - nArg--; - if( nArg==2 ) azArg[1] = azArg[2]; - } - if( nArg==2 && azArg[1][0]!='-' ){ - int i; - for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); - if( strcmp(azArg[1],"sqlite_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TABLE sqlite_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; - }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; + for(ii=1; ii1 ){ - char *zQarg = sqlite3_mprintf("%Q", azArg[1]); - if( strchr(azArg[1], '.') ){ + if( zName ){ + char *zQarg = sqlite3_mprintf("%Q", zName); + int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || + strchr(zName, '[') != 0; + if( strchr(zName, '.') ){ appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0); }else{ appendText(&sSelect, "lower(tbl_name)", 0); } - appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0); + appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0); appendText(&sSelect, zQarg, 0); + if( !bGlob ){ + appendText(&sSelect, " ESCAPE '\\' ", 0); + } appendText(&sSelect, " AND ", 0); sqlite3_free(zQarg); } appendText(&sSelect, "type!='meta' AND sql IS NOT NULL" " ORDER BY snum, rowid", 0); - rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); + if( bDebug ){ + utf8_printf(p->out, "SQL: %s;\n", sSelect.z); + }else{ + rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); + } freeText(&sSelect); } if( zErrMsg ){ @@ -5456,7 +7178,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else /* If no command name matches, show a syntax error */ session_syntax_error: - session_help(p); + showHelp(p->out, "session"); }else #endif @@ -5637,7 +7359,7 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); raw_printf(stderr, "Should be one of: --schema" - " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n"); + " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n"); rc = 1; goto meta_command_exit; } @@ -5648,7 +7370,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ zLike = z; bSeparate = 1; - if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1; + if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1; } } if( bSchema ){ @@ -5715,11 +7437,12 @@ static int do_meta_command(char *zLine, ShellState *p){ if( bDebug ){ utf8_printf(p->out, "%s\n", zSql); }else{ - shell_exec(p->db, zSql, shell_callback, p, 0); + shell_exec(p, zSql, 0); } sqlite3_free(zSql); }else +#ifndef SQLITE_NOHAVE_SYSTEM if( c=='s' && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) ){ @@ -5739,9 +7462,10 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(zCmd); if( x ) raw_printf(stderr, "System command returns %d\n", x); }else +#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ - static const char *azBool[] = { "off", "on", "full", "unk" }; + static const char *azBool[] = { "off", "on", "trigger", "full"}; int i; if( nArg!=1 ){ raw_printf(stderr, "Usage: .show\n"); @@ -5778,7 +7502,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ if( nArg==2 ){ - p->statsOn = booleanValue(azArg[1]); + p->statsOn = (u8)booleanValue(azArg[1]); }else if( nArg==1 ){ display_stats(p->db, p, 0); }else{ @@ -5799,7 +7523,10 @@ static int do_meta_command(char *zLine, ShellState *p){ initText(&s); open_db(p, 0); rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); - if( rc ) return shellDatabaseError(p->db); + if( rc ){ + sqlite3_finalize(pStmt); + return shellDatabaseError(p->db); + } if( nArg>2 && c=='i' ){ /* It is an historical accident that the .indexes command shows an error @@ -5807,6 +7534,7 @@ static int do_meta_command(char *zLine, ShellState *p){ ** command does not. */ raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); rc = 1; + sqlite3_finalize(pStmt); goto meta_command_exit; } for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ @@ -5851,18 +7579,12 @@ static int do_meta_command(char *zLine, ShellState *p){ char **azNew; int n2 = nAlloc*2 + 10; azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); - if( azNew==0 ){ - rc = shellNomemError(); - break; - } + if( azNew==0 ) shell_out_of_memory(); nAlloc = n2; azResult = azNew; } azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); - if( 0==azResult[nRow] ){ - rc = shellNomemError(); - break; - } + if( 0==azResult[nRow] ) shell_out_of_memory(); nRow++; } if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ @@ -5898,7 +7620,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* Begin redirecting output to the file "testcase-out.txt" */ if( c=='t' && strcmp(azArg[0],"testcase")==0 ){ output_reset(p); - p->out = output_file_open("testcase-out.txt"); + p->out = output_file_open("testcase-out.txt", 0); if( p->out==0 ){ raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); } @@ -5910,50 +7632,77 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #ifndef SQLITE_UNTESTABLE - if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ + if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ int ctrlCode; /* Integer code for that option */ + const char *zUsage; /* Usage notes */ } aCtrl[] = { - { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, - { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, - { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, - { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, - { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, - { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, - { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, - { "assert", SQLITE_TESTCTRL_ASSERT }, - { "always", SQLITE_TESTCTRL_ALWAYS }, - { "reserve", SQLITE_TESTCTRL_RESERVE }, - { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, - { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, - { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, - { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, - { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, - { "imposter", SQLITE_TESTCTRL_IMPOSTER }, + { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" }, + { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" }, + /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/ + /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/ + { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" }, + /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */ + { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, + { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, + { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, + { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, +#ifdef YYCOVERAGE + { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" }, +#endif + { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " }, + { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET, "" }, + { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" }, + { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" }, + { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" }, }; int testctrl = -1; - int rc2 = 0; + int iCtrl = -1; + int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ + int isOk = 0; int i, n2; + const char *zCmd = 0; + open_db(p, 0); + zCmd = nArg>=2 ? azArg[1] : "help"; + + /* The argument can optionally begin with "-" or "--" */ + if( zCmd[0]=='-' && zCmd[1] ){ + zCmd++; + if( zCmd[0]=='-' && zCmd[1] ) zCmd++; + } + + /* --help lists all test-controls */ + if( strcmp(zCmd,"help")==0 ){ + utf8_printf(p->out, "Available test-controls:\n"); + for(i=0; iout, " .testctrl %s %s\n", + aCtrl[i].zCtrlName, aCtrl[i].zUsage); + } + rc = 1; + goto meta_command_exit; + } /* convert testctrl text option to value. allow any unique prefix ** of the option name, or a numerical value. */ - n2 = strlen30(azArg[1]); + n2 = strlen30(zCmd); for(i=0; iSQLITE_TESTCTRL_LAST) ){ - utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); + if( testctrl<0 ){ + utf8_printf(stderr,"Error: unknown test-control: %s\n" + "Use \".testctrl --help\" for help\n", zCmd); }else{ switch(testctrl){ @@ -5963,10 +7712,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==3 ){ int opt = (int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); + isOk = 3; } break; @@ -5977,10 +7723,7 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_BYTEORDER: if( nArg==2 ){ rc2 = sqlite3_test_control(testctrl); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes no options\n", - azArg[1]); + isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3; } break; @@ -5989,65 +7732,57 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==3 ){ unsigned int opt = (unsigned int)integerValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single unsigned" - " int option\n", azArg[1]); + isOk = 3; } break; /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_ASSERT: case SQLITE_TESTCTRL_ALWAYS: + if( nArg==3 ){ + int opt = booleanValue(azArg[2]); + rc2 = sqlite3_test_control(testctrl, opt); + isOk = 1; + } + break; + + /* sqlite3_test_control(int, int) */ + case SQLITE_TESTCTRL_LOCALTIME_FAULT: case SQLITE_TESTCTRL_NEVER_CORRUPT: if( nArg==3 ){ int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); + isOk = 3; } break; - /* sqlite3_test_control(int, char *) */ -#ifdef SQLITE_N_KEYWORD - case SQLITE_TESTCTRL_ISKEYWORD: - if( nArg==3 ){ - const char *opt = azArg[2]; - rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr, - "Error: testctrl %s takes a single char * option\n", - azArg[1]); - } - break; -#endif - case SQLITE_TESTCTRL_IMPOSTER: if( nArg==5 ){ rc2 = sqlite3_test_control(testctrl, p->db, azArg[2], integerValue(azArg[3]), integerValue(azArg[4])); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - }else{ - raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); + isOk = 3; } break; - case SQLITE_TESTCTRL_BITVEC_TEST: - case SQLITE_TESTCTRL_FAULT_INSTALL: - case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: - case SQLITE_TESTCTRL_SCRATCHMALLOC: - default: - utf8_printf(stderr, - "Error: CLI support for testctrl %s not implemented\n", - azArg[1]); - break; +#ifdef YYCOVERAGE + case SQLITE_TESTCTRL_PARSER_COVERAGE: + if( nArg==2 ){ + sqlite3_test_control(testctrl, p->out); + isOk = 3; + } +#endif } } + if( isOk==0 && iCtrl>=0 ){ + utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage); + rc = 1; + }else if( isOk==1 ){ + raw_printf(p->out, "%d\n", rc2); + }else if( isOk==2 ){ + raw_printf(p->out, "0x%08x\n", rc2); + } }else #endif /* !defined(SQLITE_UNTESTABLE) */ @@ -6077,7 +7812,7 @@ static int do_meta_command(char *zLine, ShellState *p){ goto meta_command_exit; } output_file_close(p->traceOut); - p->traceOut = output_file_open(azArg[1]); + p->traceOut = output_file_open(azArg[1], 0); #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) if( p->traceOut==0 ){ sqlite3_trace_v2(p->db, 0, 0, 0); @@ -6101,8 +7836,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], - (int)strlen(azArg[3])); + rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3])); if( rc ){ utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); rc = 1; @@ -6113,8 +7847,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - rc = sqlite3_user_add(p->db, azArg[2], - azArg[3], (int)strlen(azArg[3]), + rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), booleanValue(azArg[4])); if( rc ){ raw_printf(stderr, "User-Add failed: %d\n", rc); @@ -6126,8 +7859,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - rc = sqlite3_user_change(p->db, azArg[2], - azArg[3], (int)strlen(azArg[3]), + rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), booleanValue(azArg[4])); if( rc ){ raw_printf(stderr, "User-Edit failed: %d\n", rc); @@ -6155,6 +7887,20 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); +#if SQLITE_HAVE_ZLIB + utf8_printf(p->out, "zlib version %s\n", zlibVersion()); +#endif +#define CTIMEOPT_VAL_(opt) #opt +#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) +#if defined(__clang__) && defined(__clang_major__) + utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." + CTIMEOPT_VAL(__clang_minor__) "." + CTIMEOPT_VAL(__clang_patchlevel__) "\n"); +#elif defined(_MSC_VER) + utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n"); +#elif defined(__GNUC__) && defined(__VERSION__) + utf8_printf(p->out, "gcc-" __VERSION__ "\n"); +#endif }else if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ @@ -6280,6 +8026,16 @@ static int line_is_command_terminator(const char *zLine){ return 0; } +/* +** We need a default sqlite3_complete() implementation to use in case +** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes +** any arbitrary text is a complete SQL statement. This is not very +** user-friendly, but it does seem to work. +*/ +#ifdef SQLITE_OMIT_COMPLETE +int sqlite3_complete(const char *zSql){ return 1; } +#endif + /* ** Return true if zSql is a complete SQL statement. Return false if it ** ends in the middle of a string literal or C-style comment. @@ -6295,7 +8051,7 @@ static int line_is_complete(char *zSql, int nSql){ } /* -** Run a single line of SQL +** Run a single line of SQL. Return the number of errors. */ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ int rc; @@ -6304,7 +8060,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ open_db(p, 0); if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql); BEGIN_TIMER; - rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); + rc = shell_exec(p, zSql, &zErrMsg); END_TIMER; if( rc || zErrMsg ){ char zPrefix[100]; @@ -6368,13 +8124,15 @@ static int process_input(ShellState *p, FILE *in){ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); continue; } - if( zLine && zLine[0]=='.' && nSql==0 ){ + if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); - rc = do_meta_command(zLine, p); - if( rc==2 ){ /* exit requested */ - break; - }else if( rc ){ - errCnt++; + if( zLine[0]=='.' ){ + rc = do_meta_command(zLine, p); + if( rc==2 ){ /* exit requested */ + break; + }else if( rc ){ + errCnt++; + } } continue; } @@ -6385,10 +8143,7 @@ static int process_input(ShellState *p, FILE *in){ if( nSql+nLine+2>=nAlloc ){ nAlloc = nSql+nLine+100; zSql = realloc(zSql, nAlloc); - if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - exit(1); - } + if( zSql==0 ) shell_out_of_memory(); } nSqlPrior = nSql; if( nSql==0 ){ @@ -6410,6 +8165,8 @@ static int process_input(ShellState *p, FILE *in){ if( p->outCount ){ output_reset(p); p->outCount = 0; + }else{ + clearTempFile(p); } }else if( nSql && _all_whitespace(zSql) ){ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql); @@ -6417,7 +8174,7 @@ static int process_input(ShellState *p, FILE *in){ } } if( nSql && !_all_whitespace(zSql) ){ - runOneSqlLine(p, zSql, in, startline); + errCnt += runOneSqlLine(p, zSql, in, startline); } free(zSql); free(zLine); @@ -6515,7 +8272,6 @@ static void process_sqliterc( " cannot read ~/.sqliterc\n"); return; } - sqlite3_initialize(); zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); sqliterc = zBuf; } @@ -6534,6 +8290,10 @@ static void process_sqliterc( ** Show available command line options */ static const char zOptions[] = +#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) + " -A ARGS... run \".archive ARGS\" and exit\n" +#endif + " -append append the database to the end of the file\n" " -ascii set output mode to 'ascii'\n" " -bail stop after hitting an error\n" " -batch force batch I/O\n" @@ -6560,14 +8320,20 @@ static const char zOptions[] = " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -quote set output mode to 'quote'\n" - " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" + " -readonly open the database read-only\n" " -separator SEP set output column separator. Default: '|'\n" +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + " -sorterref SIZE sorter references threshold size\n" +#endif " -stats print memory stats before each finalize\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" #ifdef SQLITE_ENABLE_VFSTRACE " -vfstrace enable tracing of all VFS calls\n" #endif +#ifdef SQLITE_HAVE_ZLIB + " -zip open the file as a ZIP Archive\n" +#endif ; static void usage(int showDetail){ utf8_printf(stderr, @@ -6582,6 +8348,17 @@ static void usage(int showDetail){ exit(1); } +/* +** Internal check: Verify that the SQLite is uninitialized. Print a +** error message if it is initialized. +*/ +static void verify_uninitialized(void){ + if( sqlite3_config(-1)==SQLITE_MISUSE ){ + utf8_printf(stdout, "WARNING: attempt to configure SQLite after" + " initialization.\n"); + } +} + /* ** Initialize the state information in data */ @@ -6593,6 +8370,7 @@ static void main_init(ShellState *data) { memcpy(data->rowSeparator,SEP_Row, 2); data->showHeader = 0; data->shellFlgs = SHFLG_Lookaside; + verify_uninitialized(); sqlite3_config(SQLITE_CONFIG_URI, 1); sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); sqlite3_config(SQLITE_CONFIG_MULTITHREAD); @@ -6656,35 +8434,69 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ int readStdin = 1; int nCmd = 0; char **azCmd = 0; + const char *zVfs = 0; /* Value of -vfs command-line option */ +#if !SQLITE_SHELL_IS_UTF8 + char **argvToFree = 0; + int argcToFree = 0; +#endif setBinaryMode(stdin, 0); setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); +#if !defined(_WIN32_WCE) + if( getenv("SQLITE_DEBUG_BREAK") ){ + if( isatty(0) && isatty(2) ){ + fprintf(stderr, + "attach debugger to process %d and press any key to continue.\n", + GETPID()); + fgetc(stdin); + }else{ +#if defined(_WIN32) || defined(WIN32) + DebugBreak(); +#elif defined(SIGTRAP) + raise(SIGTRAP); +#endif + } + } +#endif + #if USE_SYSTEM_SQLITE+0!=1 - if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ + if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); } #endif main_init(&data); + + /* On Windows, we must translate command-line arguments into UTF-8. + ** The SQLite memory allocator subsystem has to be enabled in order to + ** do this. But we want to run an sqlite3_shutdown() afterwards so that + ** subsequent sqlite3_config() calls will work. So copy all results into + ** memory that does not come from the SQLite memory allocator. + */ #if !SQLITE_SHELL_IS_UTF8 sqlite3_initialize(); - argv = sqlite3_malloc64(sizeof(argv[0])*argc); - if( argv==0 ){ - raw_printf(stderr, "out of memory\n"); - exit(1); - } + argvToFree = malloc(sizeof(argv[0])*argc*2); + argcToFree = argc; + argv = argvToFree + argc; + if( argv==0 ) shell_out_of_memory(); for(i=0; i=1 && argv && argv[0] ); Argv0 = argv[0]; @@ -6693,6 +8505,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ */ #ifdef SIGINT signal(SIGINT, interrupt_handler); +#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) + SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); #endif #ifdef SQLITE_SHELL_DBNAME_PROC @@ -6712,6 +8526,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ ** the size of the alternative malloc heap, ** and the first command to execute. */ + verify_uninitialized(); for(i=1; i400000 ) sz = 400000; - if( sz<2500 ) sz = 2500; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( n>10 ) n = 10; - if( n<1 ) n = 1; - sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); - data.shellFlgs |= SHFLG_Scratch; }else if( strcmp(z,"-pagecache")==0 ){ int n, sz; sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); @@ -6804,16 +8606,57 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( strcmp(z,"-mmap")==0 ){ sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + }else if( strcmp(z,"-sorterref")==0 ){ + sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); + sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz); +#endif }else if( strcmp(z,"-vfs")==0 ){ - sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); - if( pVfs ){ - sqlite3_vfs_register(pVfs, 1); - }else{ - utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); - exit(1); - } + zVfs = cmdline_option_value(argc, argv, ++i); +#ifdef SQLITE_HAVE_ZLIB + }else if( strcmp(z,"-zip")==0 ){ + data.openMode = SHELL_OPEN_ZIPFILE; +#endif + }else if( strcmp(z,"-append")==0 ){ + data.openMode = SHELL_OPEN_APPENDVFS; + }else if( strcmp(z,"-readonly")==0 ){ + data.openMode = SHELL_OPEN_READONLY; +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) + }else if( strncmp(z, "-A",2)==0 ){ + /* All remaining command-line arguments are passed to the ".archive" + ** command, so ignore them */ + break; +#endif } } + verify_uninitialized(); + + +#ifdef SQLITE_SHELL_INIT_PROC + { + /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name + ** of a C-function that will perform initialization actions on SQLite that + ** occur just before or after sqlite3_initialize(). Use this compile-time + ** option to embed this shell program in larger applications. */ + extern void SQLITE_SHELL_INIT_PROC(void); + SQLITE_SHELL_INIT_PROC(); + } +#else + /* All the sqlite3_config() calls have now been made. So it is safe + ** to call sqlite3_initialize() and process any command line -vfs option. */ + sqlite3_initialize(); +#endif + + if( zVfs ){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs); + if( pVfs ){ + sqlite3_vfs_register(pVfs, 1); + }else{ + utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); + exit(1); + } + } + if( data.zDbFilename==0 ){ #ifndef SQLITE_OMIT_MEMORYDB data.zDbFilename = ":memory:"; @@ -6824,6 +8667,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif } data.out = stdout; + sqlite3_appendvfs_init(0,0,0); /* Go ahead and open the database file if it already exists. If the ** file does not exist, delay opening it. This prevents empty database @@ -6864,6 +8708,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( strcmp(z,"-csv")==0 ){ data.mode = MODE_Csv; memcpy(data.colSeparator,",",2); +#ifdef SQLITE_HAVE_ZLIB + }else if( strcmp(z,"-zip")==0 ){ + data.openMode = SHELL_OPEN_ZIPFILE; +#endif + }else if( strcmp(z,"-append")==0 ){ + data.openMode = SHELL_OPEN_APPENDVFS; + }else if( strcmp(z,"-readonly")==0 ){ + data.openMode = SHELL_OPEN_READONLY; }else if( strcmp(z,"-ascii")==0 ){ data.mode = MODE_Ascii; sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, @@ -6886,9 +8738,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( strcmp(z,"-echo")==0 ){ ShellSetFlag(&data, SHFLG_Echo); }else if( strcmp(z,"-eqp")==0 ){ - data.autoEQP = 1; + data.autoEQP = AUTOEQP_on; }else if( strcmp(z,"-eqpfull")==0 ){ - data.autoEQP = 2; + data.autoEQP = AUTOEQP_full; }else if( strcmp(z,"-stats")==0 ){ data.statsOn = 1; }else if( strcmp(z,"-scanstats")==0 ){ @@ -6911,14 +8763,16 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdin_is_interactive = 0; }else if( strcmp(z,"-heap")==0 ){ i++; - }else if( strcmp(z,"-scratch")==0 ){ - i+=2; }else if( strcmp(z,"-pagecache")==0 ){ i+=2; }else if( strcmp(z,"-lookaside")==0 ){ i+=2; }else if( strcmp(z,"-mmap")==0 ){ i++; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + }else if( strcmp(z,"-sorterref")==0 ){ + i++; +#endif }else if( strcmp(z,"-vfs")==0 ){ i++; #ifdef SQLITE_ENABLE_VFSTRACE @@ -6943,7 +8797,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( rc && bail_on_error ) return rc==2 ? 0 : rc; }else{ open_db(&data, 0); - rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg); + rc = shell_exec(&data, z, &zErrMsg); if( zErrMsg!=0 ){ utf8_printf(stderr,"Error: %s\n", zErrMsg); if( bail_on_error ) return rc!=0 ? rc : 1; @@ -6952,6 +8806,23 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( bail_on_error ) return rc; } } +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) + }else if( strncmp(z, "-A", 2)==0 ){ + if( nCmd>0 ){ + utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands" + " with \"%s\"\n", z); + return 1; + } + open_db(&data, OPEN_DB_ZIPFILE); + if( z[2] ){ + argv[i] = &z[2]; + arDotCommand(&data, 1, argv+(i-1), argc-(i-1)); + }else{ + arDotCommand(&data, 1, argv+i, argc-i); + } + readStdin = 0; + break; +#endif }else{ utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); raw_printf(stderr,"Use -help for a list of options.\n"); @@ -6971,7 +8842,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( rc ) return rc==2 ? 0 : rc; }else{ open_db(&data, 0); - rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg); + rc = shell_exec(&data, azCmd[i], &zErrMsg); if( zErrMsg!=0 ){ utf8_printf(stderr,"Error: %s\n", zErrMsg); return rc!=0 ? rc : 1; @@ -7026,13 +8897,19 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ set_table_name(&data, 0); if( data.db ){ session_close_all(&data); - sqlite3_close(data.db); + close_db(data.db); } sqlite3_free(data.zFreeOnClose); find_home_dir(1); + output_reset(&data); + data.doXdgOpen = 0; + clearTempFile(&data); #if !SQLITE_SHELL_IS_UTF8 - for(i=0; i
 ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
 ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
 ** 
)^ ** @@ -149,9 +151,11 @@ extern "C" { ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlite3_libversion_number() function returns an integer equal to -** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the -** [SQLITE_SOURCE_ID] C preprocessor macro. +** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built +** using an edited copy of [the amalgamation], then the last four characters +** of the hash might be different from [SQLITE_SOURCE_ID].)^ ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ @@ -432,7 +436,7 @@ int sqlite3_exec( #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Not used */ +#define SQLITE_EMPTY 16 /* Internal use only */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ @@ -466,6 +470,9 @@ int sqlite3_exec( ** the most recent error can be obtained using ** [sqlite3_extended_errcode()]. */ +#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) +#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) +#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) @@ -498,17 +505,22 @@ int sqlite3_exec( #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) +#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) +#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) +#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) @@ -878,7 +890,8 @@ struct sqlite3_io_methods { **
  • [[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary -** write ahead log and shared memory files used for transaction control +** write ahead log ([WAL file]) and shared memory +** files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not @@ -1058,6 +1071,32 @@ struct sqlite3_io_methods { ** so that all subsequent write operations are independent. ** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without ** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. +** +**
  • [[SQLITE_FCNTL_LOCK_TIMEOUT]] +** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain +** a file lock using the xLock or xShmLock methods of the VFS to wait +** for up to M milliseconds before failing, where M is the single +** unsigned integer parameter. +** +**
  • [[SQLITE_FCNTL_DATA_VERSION]] +** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to +** a database file. The argument is a pointer to a 32-bit unsigned integer. +** The "data version" for the pager is written into the pointer. The +** "data version" changes whenever any change occurs to the corresponding +** database file, either through SQL statements on the same database +** connection or through transactions committed by separate database +** connections possibly in other processes. The [sqlite3_total_changes()] +** interface can be used to find if any database on the connection has changed, +** but that interface responds to changes on TEMP as well as MAIN and does +** not provide a mechanism to detect changes to MAIN only. Also, the +** [sqlite3_total_changes()] interface responds to internal changes only and +** omits changes made by other database connections. The +** [PRAGMA data_version] command provide a mechanism to detect changes to +** a single attached database that occur due to other database connections, +** but omits changes implemented by the database connection on which it is +** called. This file control is the only mechanism to detect changes that +** happen either internally or externally and that are associated with +** a particular attached database. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -1092,6 +1131,8 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31 #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 +#define SQLITE_FCNTL_LOCK_TIMEOUT 34 +#define SQLITE_FCNTL_DATA_VERSION 35 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -1129,12 +1170,18 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** in the name of the object stands for "virtual file system". See ** the [VFS | VFS documentation] for further information. ** -** The value of the iVersion field is initially 1 but may be larger in -** future versions of SQLite. Additional fields may be appended to this -** object when the iVersion value is increased. Note that the structure -** of the sqlite3_vfs object changes in the transaction between -** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not -** modified. +** The VFS interface is sometimes extended by adding new methods onto +** the end. Each time such an extension occurs, the iVersion field +** is incremented. The iVersion value started out as 1 in +** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2 +** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased +** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields +** may be appended to the sqlite3_vfs object and the iVersion value +** may increase again in future versions of SQLite. +** Note that the structure +** of the sqlite3_vfs object changes in the transition from +** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0] +** and yet the iVersion field was not modified. ** ** The szOsFile field is the size of the subclassed [sqlite3_file] ** structure used by this VFS. mxPathname is the maximum length of @@ -1662,6 +1709,16 @@ struct sqlite3_mem_methods { ** routines with a wrapper that simulations memory allocation failure or ** tracks memory usage, for example. ** +** [[SQLITE_CONFIG_SMALL_MALLOC]]
    SQLITE_CONFIG_SMALL_MALLOC
    +**
    ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of +** type int, interpreted as a boolean, which if true provides a hint to +** SQLite that it should avoid large memory allocations if possible. +** SQLite will run faster if it is free to make large memory allocations, +** but some application might prefer to run slower in exchange for +** guarantees about memory fragmentation that are possible if large +** allocations are avoided. This hint is normally off. +**
    +** ** [[SQLITE_CONFIG_MEMSTATUS]]
    SQLITE_CONFIG_MEMSTATUS
    **
    ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, ** interpreted as a boolean, which enables or disables the collection of @@ -1679,25 +1736,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_CONFIG_SCRATCH]]
    SQLITE_CONFIG_SCRATCH
    -**
    ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer -** that SQLite can use for scratch memory. ^(There are three arguments -** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte -** aligned memory buffer from which the scratch allocations will be -** drawn, the size of each scratch allocation (sz), -** and the maximum number of scratch allocations (N).)^ -** The first argument must be a pointer to an 8-byte aligned buffer -** of at least sz*N bytes of memory. -** ^SQLite will not use more than one scratch buffers per thread. -** ^SQLite will never request a scratch buffer that is more than 6 -** times the database page size. -** ^If SQLite needs needs additional -** scratch memory beyond what is provided by this configuration option, then -** [sqlite3_malloc()] will be used to obtain the memory needed.

    -** ^When the application provides any amount of scratch memory using -** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large -** [sqlite3_malloc|heap allocations]. -** This can help [Robson proof|prevent memory allocation failures] due to heap -** fragmentation in low-memory embedded systems. +**

    The SQLITE_CONFIG_SCRATCH option is no longer used. **
    ** ** [[SQLITE_CONFIG_PAGECACHE]]
    SQLITE_CONFIG_PAGECACHE
    @@ -1733,8 +1772,7 @@ struct sqlite3_mem_methods { ** [[SQLITE_CONFIG_HEAP]]
    SQLITE_CONFIG_HEAP
    **
    ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer ** that SQLite will use for all of its dynamic memory allocation needs -** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and -** [SQLITE_CONFIG_PAGECACHE]. +** beyond those provided for by [SQLITE_CONFIG_PAGECACHE]. ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns ** [SQLITE_ERROR] if invoked otherwise. @@ -1920,6 +1958,22 @@ struct sqlite3_mem_methods { ** I/O required to support statement rollback. ** The default value for this setting is controlled by the ** [SQLITE_STMTJRNL_SPILL] compile-time option. +** +** [[SQLITE_CONFIG_SORTERREF_SIZE]] +**
    SQLITE_CONFIG_SORTERREF_SIZE +**
    The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter +** of type (int) - the new value of the sorter-reference size threshold. +** Usually, when SQLite uses an external sort to order records according +** to an ORDER BY clause, all fields required by the caller are present in the +** sorted records. However, if SQLite determines based on the declared type +** of a table column that its values are likely to be very large - larger +** than the configured sorter-reference size threshold - then a reference +** is stored in each sorted record and the required column values loaded +** from the database as records are returned in sorted order. The default +** value for this option is to never use this optimization. Specifying a +** negative value for this option restores the default behaviour. +** This option is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1927,7 +1981,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ @@ -1948,6 +2002,8 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ +#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ +#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ /* ** CAPI3REF: Database Connection Configuration Options @@ -2050,8 +2106,9 @@ struct sqlite3_mem_methods { ** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to ** override this behaviour. The first parameter passed to this operation -** is an integer - non-zero to disable checkpoints-on-close, or zero (the -** default) to enable them. The second parameter is a pointer to an integer +** is an integer - positive to disable checkpoints-on-close, or zero (the +** default) to enable them, and negative to leave the setting unchanged. +** The second parameter is a pointer to an integer ** into which is written 0 or 1 to indicate whether checkpoints-on-close ** have been disabled - 0 if they are not disabled, 1 if they are. **
    @@ -2065,8 +2122,45 @@ struct sqlite3_mem_methods { ** slower. But the QPSG has the advantage of more predictable behavior. With ** the QPSG active, SQLite will always use the same query plan in the field as ** was used during testing in the lab. +** The first argument to this setting is an integer which is 0 to disable +** the QPSG, positive to enable QPSG, or negative to leave the setting +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether the QPSG is disabled or enabled +** following this call. ** ** +**
    SQLITE_DBCONFIG_TRIGGER_EQP
    +**
    By default, the output of EXPLAIN QUERY PLAN commands does not +** include output for any operations performed by trigger programs. This +** option is used to set or clear (the default) a flag that governs this +** behavior. The first parameter passed to this operation is an integer - +** positive to enable output for trigger programs, or zero to disable it, +** or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which is written +** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if +** it is not disabled, 1 if it is. +**
    +** +**
    SQLITE_DBCONFIG_RESET_DATABASE
    +**
    Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run +** [VACUUM] in order to reset a database back to an empty database +** with no schema and no content. The following process works even for +** a badly corrupted database file: +**
      +**
    1. If the database connection is newly opened, make sure it has read the +** database schema by preparing then discarding some query against the +** database, or calling sqlite3_table_column_metadata(), ignoring any +** errors. This step is only necessary if the application desires to keep +** the database in WAL mode after the reset if it was in WAL mode before +** the reset. +**
    2. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); +**
    3. [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); +**
    4. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); +**
    +** Because resetting a database is destructive and irreversible, the +** process requires the use of this obscure API and multiple steps to help +** ensure that it does not happen by accident. +**
    ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -2077,7 +2171,9 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ - +#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ +#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -2205,12 +2301,17 @@ void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** program, the value returned reflects the number of rows modified by the ** previous INSERT, UPDATE or DELETE statement within the same trigger. ** -** See also the [sqlite3_total_changes()] interface, the -** [count_changes pragma], and the [changes() SQL function]. -** ** If a separate thread makes changes on the same database connection ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. +** +** See also: +**
      +**
    • the [sqlite3_total_changes()] interface +**
    • the [count_changes pragma] +**
    • the [changes() SQL function] +**
    • the [data_version pragma] +**
    */ int sqlite3_changes(sqlite3*); @@ -2228,13 +2329,26 @@ int sqlite3_changes(sqlite3*); ** count, but those made as part of REPLACE constraint resolution are ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. -** -** See also the [sqlite3_changes()] interface, the -** [count_changes pragma], and the [total_changes() SQL function]. ** +** This the [sqlite3_total_changes(D)] interface only reports the number +** of rows that changed due to SQL statement run against database +** connection D. Any changes by other database connections are ignored. +** To detect changes against a database file from other database +** connections use the [PRAGMA data_version] command or the +** [SQLITE_FCNTL_DATA_VERSION] [file control]. +** ** If a separate thread makes changes on the same database connection ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. +** +** See also: +**
      +**
    • the [sqlite3_changes()] interface +**
    • the [count_changes pragma] +**
    • the [changes() SQL function] +**
    • the [data_version pragma] +**
    • the [SQLITE_FCNTL_DATA_VERSION] [file control] +**
    */ int sqlite3_total_changes(sqlite3*); @@ -2483,16 +2597,16 @@ void sqlite3_free_table(char **result); ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. -** These routines understand most of the common K&R formatting options, -** plus some additional non-standard formats, detailed below. -** Note that some of the more obscure formatting options from recent -** C-library standards are omitted from this implementation. +** These routines understand most of the common formatting options from +** the standard library printf() +** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]). +** See the [built-in printf()] documentation for details. ** ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their -** results into memory obtained from [sqlite3_malloc()]. +** results into memory obtained from [sqlite3_malloc64()]. ** The strings returned by these two routines should be ** released by [sqlite3_free()]. ^Both routines return a -** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough ** memory to hold the resulting string. ** ** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from @@ -2516,71 +2630,7 @@ void sqlite3_free_table(char **result); ** ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). ** -** These routines all implement some additional formatting -** options that are useful for constructing SQL statements. -** All of the usual printf() formatting options apply. In addition, there -** is are "%q", "%Q", "%w" and "%z" options. -** -** ^(The %q option works like %s in that it substitutes a nul-terminated -** string from the argument list. But %q also doubles every '\'' character. -** %q is designed for use inside a string literal.)^ By doubling each '\'' -** character it escapes that character and allows it to be inserted into -** the string. -** -** For example, assume the string variable zText contains text as follows: -** -**
    -**  char *zText = "It's a happy day!";
    -** 
    -** -** One can use this text in an SQL statement as follows: -** -**
    -**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
    -**  sqlite3_exec(db, zSQL, 0, 0, 0);
    -**  sqlite3_free(zSQL);
    -** 
    -** -** Because the %q format string is used, the '\'' character in zText -** is escaped and the SQL generated is as follows: -** -**
    -**  INSERT INTO table1 VALUES('It''s a happy day!')
    -** 
    -** -** This is correct. Had we used %s instead of %q, the generated SQL -** would have looked like this: -** -**
    -**  INSERT INTO table1 VALUES('It's a happy day!');
    -** 
    -** -** This second example is an SQL syntax error. As a general rule you should -** always use %q instead of %s when inserting text into a string literal. -** -** ^(The %Q option works like %q except it also adds single quotes around -** the outside of the total string. Additionally, if the parameter in the -** argument list is a NULL pointer, %Q substitutes the text "NULL" (without -** single quotes).)^ So, for example, one could say: -** -**
    -**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
    -**  sqlite3_exec(db, zSQL, 0, 0, 0);
    -**  sqlite3_free(zSQL);
    -** 
    -** -** The code above will render a correct SQL statement in the zSQL -** variable even if the zText variable is a NULL pointer. -** -** ^(The "%w" formatting option is like "%q" except that it expects to -** be contained within double-quotes instead of single quotes, and it -** escapes the double-quote character instead of the single-quote -** character.)^ The "%w" formatting option is intended for safely inserting -** table and column names into a constructed SQL statement. -** -** ^(The "%z" formatting option works like "%s" but with the -** addition that after the string has been read and copied into -** the result, [sqlite3_free()] is called on the input string.)^ +** See also: [built-in printf()], [printf() SQL function] */ char *sqlite3_mprintf(const char*,...); char *sqlite3_vmprintf(const char*, va_list); @@ -2938,8 +2988,8 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** KEYWORDS: SQLITE_TRACE ** ** These constants identify classes of events that can be monitored -** using the [sqlite3_trace_v2()] tracing logic. The third argument -** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of +** using the [sqlite3_trace_v2()] tracing logic. The M argument +** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of ** the following constants. ^The first argument to the trace callback ** is one of the following constants. ** @@ -3148,10 +3198,10 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ^If [URI filename] interpretation is enabled, and the filename argument ** begins with "file:", then the filename is interpreted as a URI. ^URI ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is -** set in the fourth argument to sqlite3_open_v2(), or if it has +** set in the third argument to sqlite3_open_v2(), or if it has ** been enabled globally using the [SQLITE_CONFIG_URI] option with the ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. -** As of SQLite version 3.7.7, URI filename interpretation is turned off +** URI filename interpretation is turned off ** by default, but future releases of SQLite might enable URI filename ** interpretation by default. See "[URI filenames]" for additional ** information. @@ -3354,13 +3404,24 @@ sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); ** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. -** If the most recent API call was successful, -** then the return value from sqlite3_errcode() is undefined. ** ^The sqlite3_extended_errcode() ** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** +** The values returned by sqlite3_errcode() and/or +** sqlite3_extended_errcode() might change with each API call. +** Except, there are some interfaces that are guaranteed to never +** change the value of the error code. The error-code preserving +** interfaces are: +** +**
      +**
    • sqlite3_errcode() +**
    • sqlite3_extended_errcode() +**
    • sqlite3_errmsg() +**
    • sqlite3_errmsg16() +**
    +** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. ** ^(Memory to hold the error message string is managed internally. @@ -3646,13 +3707,13 @@ int sqlite3_limit(sqlite3*, int id, int newVal); ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. **
  • +** ** **

    ^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having ** the extra prepFlags parameter, which is a bit array consisting of zero or ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The ** sqlite3_prepare_v2() interface works exactly the same as ** sqlite3_prepare_v3() with a zero prepFlags parameter. -** */ int sqlite3_prepare( sqlite3 *db, /* Database handle */ @@ -3825,8 +3886,9 @@ int sqlite3_stmt_busy(sqlite3_stmt*); ** implementation of [application-defined SQL functions] are protected. ** ^The sqlite3_value object returned by ** [sqlite3_column_value()] is unprotected. -** Unprotected sqlite3_value objects may only be used with -** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** Unprotected sqlite3_value objects may only be used as arguments +** to [sqlite3_result_value()], [sqlite3_bind_value()], and +** [sqlite3_value_dup()]. ** The [sqlite3_value_blob | sqlite3_value_type()] family of ** interfaces require protected sqlite3_value objects. */ @@ -4513,11 +4575,25 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** -** ^(If a memory allocation error occurs during the evaluation of any -** of these routines, a default value is returned. The default value -** is either the integer 0, the floating point number 0.0, or a NULL -** pointer. Subsequent calls to [sqlite3_errcode()] will return -** [SQLITE_NOMEM].)^ +** As long as the input parameters are correct, these routines will only +** fail if an out-of-memory error occurs during a format conversion. +** Only the following subset of interfaces are subject to out-of-memory +** errors: +** +**

      +**
    • sqlite3_column_blob() +**
    • sqlite3_column_text() +**
    • sqlite3_column_text16() +**
    • sqlite3_column_bytes() +**
    • sqlite3_column_bytes16() +**
    +** +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** Valid SQL NULL returns can be distinguished from out-of-memory errors +** by invoking the [sqlite3_errcode()] immediately after the suspect +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. */ const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); double sqlite3_column_double(sqlite3_stmt*, int iCol); @@ -4594,11 +4670,13 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior -** of existing SQL functions or aggregates. The only differences between -** these routines are the text encoding expected for -** the second parameter (the name of the function being created) -** and the presence or absence of a destructor callback for -** the application data pointer. +** of existing SQL functions or aggregates. The only differences between +** the three "sqlite3_create_function*" routines are the text encoding +** expected for the second parameter (the name of the function being +** created) and the presence or absence of a destructor callback for +** the application data pointer. Function sqlite3_create_window_function() +** is similar, but allows the user to supply the extra callback functions +** needed by [aggregate window functions]. ** ** ^The first parameter is the [database connection] to which the SQL ** function is to be added. ^If an application uses more than one database @@ -4644,7 +4722,8 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ ** -** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** ^The sixth, seventh and eighth parameters passed to the three +** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc ** callback only; NULL pointers must be passed as the xStep and xFinal @@ -4653,15 +4732,24 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** SQL function or aggregate, pass NULL pointers for all three function ** callbacks. ** -** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, -** then it is destructor for the application data pointer. -** The destructor is invoked when the function is deleted, either by being -** overloaded or when the database connection closes.)^ -** ^The destructor is also invoked if the call to -** sqlite3_create_function_v2() fails. -** ^When the destructor callback of the tenth parameter is invoked, it -** is passed a single argument which is a copy of the application data -** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue +** and xInverse) passed to sqlite3_create_window_function are pointers to +** C-language callbacks that implement the new function. xStep and xFinal +** must both be non-NULL. xValue and xInverse may either both be NULL, in +** which case a regular aggregate function is created, or must both be +** non-NULL, in which case the new function may be used as either an aggregate +** or aggregate window function. More details regarding the implementation +** of aggregate window functions are +** [user-defined window functions|available here]. +** +** ^(If the final parameter to sqlite3_create_function_v2() or +** sqlite3_create_window_function() is not NULL, then it is destructor for +** the application data pointer. The destructor is invoked when the function +** is deleted, either by being overloaded or when the database connection +** closes.)^ ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. ^When the destructor callback is +** invoked, it is passed a single argument which is a copy of the application +** data pointer which was the fifth parameter to sqlite3_create_function_v2(). ** ** ^It is permitted to register multiple implementations of the same ** functions with the same name but with either differing numbers of @@ -4714,6 +4802,18 @@ int sqlite3_create_function_v2( void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*) ); +int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +); /* ** CAPI3REF: Text Encodings @@ -4784,6 +4884,9 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** datatype of the value **
    sqlite3_value_numeric_type   ** →  Best numeric datatype of the value +**
    sqlite3_value_nochange   +** →  True if the column is unchanged in an UPDATE +** against a virtual table. **
    ** ** Details: @@ -4832,6 +4935,19 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** then the conversion is performed. Otherwise no conversion occurs. ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** +** ^Within the [xUpdate] method of a [virtual table], the +** sqlite3_value_nochange(X) interface returns true if and only if +** the column corresponding to X is unchanged by the UPDATE operation +** that the xUpdate method call was invoked to implement and if +** and the prior [xColumn] method call that was invoked to extracted +** the value for that column returned without setting a result (probably +** because it queried [sqlite3_vtab_nochange()] and found that the column +** was unchanging). ^Within an [xUpdate] method, any value for which +** sqlite3_value_nochange(X) is true will in all other respects appear +** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other +** than within an [xUpdate] method call for an UPDATE statement, then +** the return value is arbitrary and meaningless. +** ** Please pay particular attention to the fact that the pointer returned ** from [sqlite3_value_blob()], [sqlite3_value_text()], or ** [sqlite3_value_text16()] can be invalidated by a subsequent call to @@ -4840,6 +4956,28 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. +** +** As long as the input parameter is correct, these routines can only +** fail if an out-of-memory error occurs during a format conversion. +** Only the following subset of interfaces are subject to out-of-memory +** errors: +** +**
      +**
    • sqlite3_value_blob() +**
    • sqlite3_value_text() +**
    • sqlite3_value_text16() +**
    • sqlite3_value_text16le() +**
    • sqlite3_value_text16be() +**
    • sqlite3_value_bytes() +**
    • sqlite3_value_bytes16() +**
    +** +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** Valid SQL NULL returns can be distinguished from out-of-memory errors +** by invoking the [sqlite3_errcode()] immediately after the suspect +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. */ const void *sqlite3_value_blob(sqlite3_value*); double sqlite3_value_double(sqlite3_value*); @@ -4854,6 +4992,7 @@ int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); int sqlite3_value_numeric_type(sqlite3_value*); +int sqlite3_value_nochange(sqlite3_value*); /* ** CAPI3REF: Finding The Subtype Of SQL Values @@ -5509,6 +5648,41 @@ SQLITE_EXTERN char *sqlite3_temp_directory; */ SQLITE_EXTERN char *sqlite3_data_directory; +/* +** CAPI3REF: Win32 Specific Interface +** +** These interfaces are available only on Windows. The +** [sqlite3_win32_set_directory] interface is used to set the value associated +** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to +** zValue, depending on the value of the type parameter. The zValue parameter +** should be NULL to cause the previous value to be freed via [sqlite3_free]; +** a non-NULL value will be copied into memory obtained from [sqlite3_malloc] +** prior to being used. The [sqlite3_win32_set_directory] interface returns +** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported, +** or [SQLITE_NOMEM] if memory could not be allocated. The value of the +** [sqlite3_data_directory] variable is intended to act as a replacement for +** the current directory on the sub-platforms of Win32 where that concept is +** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and +** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the +** sqlite3_win32_set_directory interface except the string parameter must be +** UTF-8 or UTF-16, respectively. +*/ +int sqlite3_win32_set_directory( + unsigned long type, /* Identifier for directory being set or reset */ + void *zValue /* New value for directory being set or reset */ +); +int sqlite3_win32_set_directory8(unsigned long type, const char *zValue); +int sqlite3_win32_set_directory16(unsigned long type, const void *zValue); + +/* +** CAPI3REF: Win32 Directory Types +** +** These macros are only available on Windows. They define the allowed values +** for the type argument to the [sqlite3_win32_set_directory] interface. +*/ +#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1 +#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2 + /* ** CAPI3REF: Test For Auto-Commit Mode ** KEYWORDS: {autocommit mode} @@ -6241,6 +6415,10 @@ struct sqlite3_index_info { /* ** CAPI3REF: Virtual Table Scan Flags +** +** Virtual table implementations are allowed to set the +** [sqlite3_index_info].idxFlags field to some combination of +** these bits. */ #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ @@ -6252,15 +6430,21 @@ struct sqlite3_index_info { ** an operator that is part of a constraint term in the wHERE clause of ** a query that uses a [virtual table]. */ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_NE 68 +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 +#define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -6937,6 +7121,7 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files ** METHOD: sqlite3 +** KEYWORDS: {file control} ** ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated @@ -6951,11 +7136,18 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** the xFileControl method. ^The return value of the xFileControl ** method becomes the return value of this routine. ** -** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** A few opcodes for [sqlite3_file_control()] are handled directly +** by the SQLite core and never invoke the +** sqlite3_io_methods.xFileControl method. +** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes ** a pointer to the underlying [sqlite3_file] object to be written into -** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER -** case is a short-circuit path which does not actually invoke the -** underlying sqlite3_io_methods.xFileControl method. +** the space pointed to by the 4th parameter. The +** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns +** the [sqlite3_file] object associated with the journal file instead of +** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns +** a pointer to the underlying [sqlite3_vfs] object for the file. +** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter +** from the pager. ** ** ^If the second parameter (zDbName) does not match the name of any ** open database file, then SQLITE_ERROR is returned. ^This error @@ -6965,7 +7157,7 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** an incorrect zDbName and an SQLITE_ERROR return from the underlying ** xFileControl method. ** -** See also: [SQLITE_FCNTL_LOCKSTATE] +** See also: [file control opcodes] */ int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); @@ -7011,8 +7203,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 -#define SQLITE_TESTCTRL_ISKEYWORD 16 -#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 @@ -7022,7 +7214,191 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 #define SQLITE_TESTCTRL_IMPOSTER 25 -#define SQLITE_TESTCTRL_LAST 25 +#define SQLITE_TESTCTRL_PARSER_COVERAGE 26 +#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */ + +/* +** CAPI3REF: SQL Keyword Checking +** +** These routines provide access to the set of SQL language keywords +** recognized by SQLite. Applications can uses these routines to determine +** whether or not a specific identifier needs to be escaped (for example, +** by enclosing in double-quotes) so as not to confuse the parser. +** +** The sqlite3_keyword_count() interface returns the number of distinct +** keywords understood by SQLite. +** +** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and +** makes *Z point to that keyword expressed as UTF8 and writes the number +** of bytes in the keyword into *L. The string that *Z points to is not +** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns +** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z +** or L are NULL or invalid pointers then calls to +** sqlite3_keyword_name(N,Z,L) result in undefined behavior. +** +** The sqlite3_keyword_check(Z,L) interface checks to see whether or not +** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero +** if it is and zero if not. +** +** The parser used by SQLite is forgiving. It is often possible to use +** a keyword as an identifier as long as such use does not result in a +** parsing ambiguity. For example, the statement +** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and +** creates a new table named "BEGIN" with three columns named +** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid +** using keywords as identifiers. Common techniques used to avoid keyword +** name collisions include: +**
      +**
    • Put all identifier names inside double-quotes. This is the official +** SQL way to escape identifier names. +**
    • Put identifier names inside [...]. This is not standard SQL, +** but it is what SQL Server does and so lots of programmers use this +** technique. +**
    • Begin every identifier with the letter "Z" as no SQL keywords start +** with "Z". +**
    • Include a digit somewhere in every identifier name. +**
    +** +** Note that the number of keywords understood by SQLite can depend on +** compile-time options. For example, "VACUUM" is not a keyword if +** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also, +** new keywords may be added to future releases of SQLite. +*/ +int sqlite3_keyword_count(void); +int sqlite3_keyword_name(int,const char**,int*); +int sqlite3_keyword_check(const char*,int); + +/* +** CAPI3REF: Dynamic String Object +** KEYWORDS: {dynamic string} +** +** An instance of the sqlite3_str object contains a dynamically-sized +** string under construction. +** +** The lifecycle of an sqlite3_str object is as follows: +**
      +**
    1. ^The sqlite3_str object is created using [sqlite3_str_new()]. +**
    2. ^Text is appended to the sqlite3_str object using various +** methods, such as [sqlite3_str_appendf()]. +**
    3. ^The sqlite3_str object is destroyed and the string it created +** is returned using the [sqlite3_str_finish()] interface. +**
    +*/ +typedef struct sqlite3_str sqlite3_str; + +/* +** CAPI3REF: Create A New Dynamic String Object +** CONSTRUCTOR: sqlite3_str +** +** ^The [sqlite3_str_new(D)] interface allocates and initializes +** a new [sqlite3_str] object. To avoid memory leaks, the object returned by +** [sqlite3_str_new()] must be freed by a subsequent call to +** [sqlite3_str_finish(X)]. +** +** ^The [sqlite3_str_new(D)] interface always returns a pointer to a +** valid [sqlite3_str] object, though in the event of an out-of-memory +** error the returned object might be a special singleton that will +** silently reject new text, always return SQLITE_NOMEM from +** [sqlite3_str_errcode()], always return 0 for +** [sqlite3_str_length()], and always return NULL from +** [sqlite3_str_finish(X)]. It is always safe to use the value +** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter +** to any of the other [sqlite3_str] methods. +** +** The D parameter to [sqlite3_str_new(D)] may be NULL. If the +** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum +** length of the string contained in the [sqlite3_str] object will be +** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead +** of [SQLITE_MAX_LENGTH]. +*/ +sqlite3_str *sqlite3_str_new(sqlite3*); + +/* +** CAPI3REF: Finalize A Dynamic String +** DESTRUCTOR: sqlite3_str +** +** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X +** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] +** that contains the constructed string. The calling application should +** pass the returned value to [sqlite3_free()] to avoid a memory leak. +** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any +** errors were encountered during construction of the string. ^The +** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the +** string in [sqlite3_str] object X is zero bytes long. +*/ +char *sqlite3_str_finish(sqlite3_str*); + +/* +** CAPI3REF: Add Content To A Dynamic String +** METHOD: sqlite3_str +** +** These interfaces add content to an sqlite3_str object previously obtained +** from [sqlite3_str_new()]. +** +** ^The [sqlite3_str_appendf(X,F,...)] and +** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] +** functionality of SQLite to append formatted text onto the end of +** [sqlite3_str] object X. +** +** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S +** onto the end of the [sqlite3_str] object X. N must be non-negative. +** S must contain at least N non-zero bytes of content. To append a +** zero-terminated string in its entirety, use the [sqlite3_str_appendall()] +** method instead. +** +** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of +** zero-terminated string S onto the end of [sqlite3_str] object X. +** +** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the +** single-byte character C onto the end of [sqlite3_str] object X. +** ^This method can be used, for example, to add whitespace indentation. +** +** ^The [sqlite3_str_reset(X)] method resets the string under construction +** inside [sqlite3_str] object X back to zero bytes in length. +** +** These methods do not return a result code. ^If an error occurs, that fact +** is recorded in the [sqlite3_str] object and can be recovered by a +** subsequent call to [sqlite3_str_errcode(X)]. +*/ +void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); +void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); +void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); +void sqlite3_str_appendall(sqlite3_str*, const char *zIn); +void sqlite3_str_appendchar(sqlite3_str*, int N, char C); +void sqlite3_str_reset(sqlite3_str*); + +/* +** CAPI3REF: Status Of A Dynamic String +** METHOD: sqlite3_str +** +** These interfaces return the current status of an [sqlite3_str] object. +** +** ^If any prior errors have occurred while constructing the dynamic string +** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return +** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns +** [SQLITE_NOMEM] following any out-of-memory error, or +** [SQLITE_TOOBIG] if the size of the dynamic string exceeds +** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors. +** +** ^The [sqlite3_str_length(X)] method returns the current length, in bytes, +** of the dynamic string under construction in [sqlite3_str] object X. +** ^The length returned by [sqlite3_str_length(X)] does not include the +** zero-termination byte. +** +** ^The [sqlite3_str_value(X)] method returns a pointer to the current +** content of the dynamic string under construction in X. The value +** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X +** and might be freed or altered by any subsequent method on the same +** [sqlite3_str] object. Applications must not used the pointer returned +** [sqlite3_str_value(X)] after any subsequent method call on the same +** object. ^Applications may change the content of the string returned +** by [sqlite3_str_value(X)] as long as they do not write into any bytes +** outside the range of 0 to [sqlite3_str_length(X)] and do not read or +** write any byte after any subsequent sqlite3_str method call. +*/ +int sqlite3_str_errcode(sqlite3_str*); +int sqlite3_str_length(sqlite3_str*); +char *sqlite3_str_value(sqlite3_str*); /* ** CAPI3REF: SQLite Runtime Status @@ -7071,8 +7447,7 @@ int sqlite3_status64( **
    This parameter is the current amount of memory checked out ** using [sqlite3_malloc()], either directly or indirectly. The ** figure includes calls made to [sqlite3_malloc()] by the application -** and internal memory usage by the SQLite library. Scratch memory -** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** and internal memory usage by the SQLite library. Auxiliary page-cache ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in ** this parameter. The amount returned is the sum of the allocation ** sizes as reported by the xSize method in [sqlite3_mem_methods].
    )^ @@ -7110,29 +7485,14 @@ int sqlite3_status64( ** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
    )^ ** -** [[SQLITE_STATUS_SCRATCH_USED]] ^(
    SQLITE_STATUS_SCRATCH_USED
    -**
    This parameter returns the number of allocations used out of the -** [scratch memory allocator] configured using -** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not -** in bytes. Since a single thread may only have one scratch allocation -** outstanding at time, this parameter also reports the number of threads -** using scratch memory at the same time.
    )^ +** [[SQLITE_STATUS_SCRATCH_USED]]
    SQLITE_STATUS_SCRATCH_USED
    +**
    No longer used.
    ** ** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
    SQLITE_STATUS_SCRATCH_OVERFLOW
    -**
    This parameter returns the number of bytes of scratch memory -** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] -** buffer and where forced to overflow to [sqlite3_malloc()]. The values -** returned include overflows because the requested allocation was too -** larger (that is, because the requested allocation was larger than the -** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer -** slots were available. -**
    )^ +**
    No longer used.
    ** -** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
    SQLITE_STATUS_SCRATCH_SIZE
    -**
    This parameter records the largest memory allocation request -** handed to [scratch memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. -** The value written into the *pCurrent parameter is undefined.
    )^ +** [[SQLITE_STATUS_SCRATCH_SIZE]]
    SQLITE_STATUS_SCRATCH_SIZE
    +**
    No longer used.
    ** ** [[SQLITE_STATUS_PARSER_STACK]] ^(
    SQLITE_STATUS_PARSER_STACK
    **
    The *pHighwater parameter records the deepest parser stack. @@ -7145,12 +7505,12 @@ int sqlite3_status64( #define SQLITE_STATUS_MEMORY_USED 0 #define SQLITE_STATUS_PAGECACHE_USED 1 #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 -#define SQLITE_STATUS_SCRATCH_USED 3 -#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */ +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */ #define SQLITE_STATUS_MALLOC_SIZE 5 #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 -#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */ #define SQLITE_STATUS_MALLOC_COUNT 9 /* @@ -7273,6 +7633,15 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. **
    ** +** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(
    SQLITE_DBSTATUS_CACHE_SPILL
    +**
    This parameter returns the number of dirty cache entries that have +** been written to disk in the middle of a transaction due to the page +** cache overflowing. Transactions are more efficient if they are written +** to disk all at once. When pages spill mid-transaction, that introduces +** additional overhead. This parameter can be used help identify +** inefficiencies that can be resolve by increasing the cache size. +**
    +** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
    SQLITE_DBSTATUS_DEFERRED_FKS
    **
    This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been @@ -7292,7 +7661,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 -#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */ +#define SQLITE_DBSTATUS_CACHE_SPILL 12 +#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */ /* @@ -8292,6 +8662,40 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); */ int sqlite3_vtab_on_conflict(sqlite3 *); +/* +** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE +** +** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] +** method of a [virtual table], then it returns true if and only if the +** column is being fetched as part of an UPDATE operation during which the +** column value will not change. Applications might use this to substitute +** a return value that is less expensive to compute and that the corresponding +** [xUpdate] method understands as a "no-change" value. +** +** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that +** the column is not changed by the UPDATE statement, then the xColumn +** method can optionally return without setting a result, without calling +** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. +** In that case, [sqlite3_value_nochange(X)] will return true for the +** same column in the [xUpdate] method. +*/ +int sqlite3_vtab_nochange(sqlite3_context*); + +/* +** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** +** This function may only be called from within a call to the [xBestIndex] +** method of a [virtual table]. +** +** The first argument must be the sqlite3_index_info object that is the +** first parameter to the xBestIndex() method. The second argument must be +** an index into the aConstraint[] array belonging to the sqlite3_index_info +** structure passed to xBestIndex. This function returns a pointer to a buffer +** containing the name of the collation sequence for the corresponding +** constraint. +*/ +SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); + /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} @@ -8562,7 +8966,6 @@ int sqlite3_system_errno(sqlite3*); /* ** CAPI3REF: Database Snapshot ** KEYWORDS: {snapshot} {sqlite3_snapshot} -** EXPERIMENTAL ** ** An instance of the snapshot object records the state of a [WAL mode] ** database for some specific point in history. @@ -8579,11 +8982,6 @@ int sqlite3_system_errno(sqlite3*); ** version of the database file so that it is possible to later open a new read ** transaction that sees that historical version of the database rather than ** the most recent version. -** -** The constructor for this object is [sqlite3_snapshot_get()]. The -** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer -** to an historical snapshot (if possible). The destructor for -** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. */ typedef struct sqlite3_snapshot { unsigned char hidden[48]; @@ -8591,7 +8989,7 @@ typedef struct sqlite3_snapshot { /* ** CAPI3REF: Record A Database Snapshot -** EXPERIMENTAL +** CONSTRUCTOR: sqlite3_snapshot ** ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a ** new [sqlite3_snapshot] object that records the current state of @@ -8607,7 +9005,7 @@ typedef struct sqlite3_snapshot { ** in this case. ** **
      -**
    • The database handle must be in [autocommit mode]. +**
    • The database handle must not be in [autocommit mode]. ** **
    • Schema S of [database connection] D must be a [WAL mode] database. ** @@ -8630,7 +9028,7 @@ typedef struct sqlite3_snapshot { ** to avoid a memory leak. ** ** The [sqlite3_snapshot_get()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( sqlite3 *db, @@ -8640,24 +9038,35 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( /* ** CAPI3REF: Start a read transaction on an historical snapshot -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** -** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a -** read transaction for schema S of -** [database connection] D such that the read transaction -** refers to historical [snapshot] P, rather than the most -** recent change to the database. -** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success -** or an appropriate [error code] if it fails. +** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read +** transaction or upgrades an existing one for schema S of +** [database connection] D such that the read transaction refers to +** historical [snapshot] P, rather than the most recent change to the +** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK +** on success or an appropriate [error code] if it fails. +** +** ^In order to succeed, the database connection must not be in +** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there +** is already a read transaction open on schema S, then the database handle +** must have no active statements (SELECT statements that have been passed +** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). +** SQLITE_ERROR is returned if either of these conditions is violated, or +** if schema S does not exist, or if the snapshot object is invalid. +** +** ^A call to sqlite3_snapshot_open() will fail to open if the specified +** snapshot has been overwritten by a [checkpoint]. In this case +** SQLITE_ERROR_SNAPSHOT is returned. +** +** If there is already a read transaction open when this function is +** invoked, then the same read transaction remains open (on the same +** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT +** is returned. If another error code - for example SQLITE_PROTOCOL or an +** SQLITE_IOERR error code - is returned, then the final state of the +** read transaction is undefined. If SQLITE_OK is returned, then the +** read transaction is now open on database snapshot P. ** -** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be -** the first operation following the [BEGIN] that takes the schema S -** out of [autocommit mode]. -** ^In other words, schema S must not currently be in -** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the -** database connection D must be out of [autocommit mode]. -** ^A [snapshot] will fail to open if it has been overwritten by a -** [checkpoint]. ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the ** database connection D does not know that the database file for ** schema S is in [WAL mode]. A database connection might not know @@ -8668,7 +9077,7 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( ** database connection in order to make it ready to use snapshots.) ** ** The [sqlite3_snapshot_open()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( sqlite3 *db, @@ -8678,20 +9087,20 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( /* ** CAPI3REF: Destroy a snapshot -** EXPERIMENTAL +** DESTRUCTOR: sqlite3_snapshot ** ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. ** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** ** The [sqlite3_snapshot_free()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** CAPI3REF: Compare the ages of two snapshot handles. -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages ** of two valid snapshot handles. @@ -8710,6 +9119,9 @@ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); ** Otherwise, this API returns a negative value if P1 refers to an older ** snapshot than P2, zero if the two handles refer to the same database ** snapshot, and a positive value if P1 is a newer snapshot than P2. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p1, @@ -8718,26 +9130,151 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( /* ** CAPI3REF: Recover snapshots from a wal file -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** -** If all connections disconnect from a database file but do not perform -** a checkpoint, the existing wal file is opened along with the database -** file the next time the database is opened. At this point it is only -** possible to successfully call sqlite3_snapshot_open() to open the most -** recent snapshot of the database (the one at the head of the wal file), -** even though the wal file may contain other valid snapshots for which -** clients have sqlite3_snapshot handles. +** If a [WAL file] remains on disk after all database connections close +** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control] +** or because the last process to have the database opened exited without +** calling [sqlite3_close()]) and a new connection is subsequently opened +** on that database and [WAL file], the [sqlite3_snapshot_open()] interface +** will only be able to open the last transaction added to the WAL file +** even though the WAL file contains other valid transactions. ** -** This function attempts to scan the wal file associated with database zDb +** This function attempts to scan the WAL file associated with database zDb ** of database handle db and make all valid snapshots available to ** sqlite3_snapshot_open(). It is an error if there is already a read -** transaction open on the database, or if the database is not a wal mode +** transaction open on the database, or if the database is not a WAL mode ** database. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); +/* +** CAPI3REF: Serialize a database +** +** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory +** that is a serialization of the S database on [database connection] D. +** If P is not a NULL pointer, then the size of the database in bytes +** is written into *P. +** +** For an ordinary on-disk database file, the serialization is just a +** copy of the disk file. For an in-memory database or a "TEMP" database, +** the serialization is the same sequence of bytes which would be written +** to disk if that database where backed up to disk. +** +** The usual case is that sqlite3_serialize() copies the serialization of +** the database into memory obtained from [sqlite3_malloc64()] and returns +** a pointer to that memory. The caller is responsible for freeing the +** returned value to avoid a memory leak. However, if the F argument +** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations +** are made, and the sqlite3_serialize() function will return a pointer +** to the contiguous memory representation of the database that SQLite +** is currently using for that database, or NULL if the no such contiguous +** memory representation of the database exists. A contiguous memory +** representation of the database will usually only exist if there has +** been a prior call to [sqlite3_deserialize(D,S,...)] with the same +** values of D and S. +** The size of the database is written into *P even if the +** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy +** of the database exists. +** +** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the +** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory +** allocation error occurs. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_DESERIALIZE] option. +*/ +unsigned char *sqlite3_serialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */ + sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */ + unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3_serialize +** +** Zero or more of the following constants can be OR-ed together for +** the F argument to [sqlite3_serialize(D,S,P,F)]. +** +** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return +** a pointer to contiguous in-memory database that it is currently using, +** without making a copy of the database. If SQLite is not currently using +** a contiguous in-memory database, then this option causes +** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be +** using a contiguous in-memory database if it has been initialized by a +** prior call to [sqlite3_deserialize()]. +*/ +#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */ + +/* +** CAPI3REF: Deserialize a database +** +** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the +** [database connection] D to disconnect from database S and then +** reopen S as an in-memory database based on the serialization contained +** in P. The serialized database P is N bytes in size. M is the size of +** the buffer P, which might be larger than N. If M is larger than N, and +** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is +** permitted to add content to the in-memory database as long as the total +** size does not exceed M bytes. +** +** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will +** invoke sqlite3_free() on the serialization buffer when the database +** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then +** SQLite will try to increase the buffer size using sqlite3_realloc64() +** if writes on the database cause it to grow larger than M bytes. +** +** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the +** database is currently in a read transaction or is involved in a backup +** operation. +** +** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the +** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then +** [sqlite3_free()] is invoked on argument P prior to returning. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_DESERIALIZE] option. +*/ +int sqlite3_deserialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which DB to reopen with the deserialization */ + unsigned char *pData, /* The serialized database content */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ + sqlite3_int64 szBuf, /* Total size of buffer pData[] */ + unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3_deserialize() +** +** The following are allowed values for 6th argument (the F argument) to +** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. +** +** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization +** in the P argument is held in memory obtained from [sqlite3_malloc64()] +** and that SQLite should take ownership of this memory and automatically +** free it when it has finished using it. Without this flag, the caller +** is responsible for freeing any dynamically allocated memory. +** +** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to +** grow the size of the database using calls to [sqlite3_realloc64()]. This +** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used. +** Without this flag, the deserialized database cannot increase in size beyond +** the number of bytes specified by the M parameter. +** +** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database +** should be treated as read-only. +*/ +#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ +#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ +#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 4aade278bd..35d9950cf6 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -134,7 +134,7 @@ struct sqlite3_api_routines { int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, const char*,const char*),void*); void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); - char * (*snprintf)(int,char*,const char*,...); + char * (*xsnprintf)(int,char*,const char*,...); int (*step)(sqlite3_stmt*); int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, char const**,char const**,int*,int*,int*); @@ -292,6 +292,30 @@ struct sqlite3_api_routines { int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); void *(*value_pointer)(sqlite3_value*,const char*); + int (*vtab_nochange)(sqlite3_context*); + int (*value_nochange)(sqlite3_value*); + const char *(*vtab_collation)(sqlite3_index_info*,int); + /* Version 3.24.0 and later */ + int (*keyword_count)(void); + int (*keyword_name)(int,const char**,int*); + int (*keyword_check)(const char*,int); + sqlite3_str *(*str_new)(sqlite3*); + char *(*str_finish)(sqlite3_str*); + void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); + void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); + void (*str_append)(sqlite3_str*, const char *zIn, int N); + void (*str_appendall)(sqlite3_str*, const char *zIn); + void (*str_appendchar)(sqlite3_str*, int N, char C); + void (*str_reset)(sqlite3_str*); + int (*str_errcode)(sqlite3_str*); + int (*str_length)(sqlite3_str*); + char *(*str_value)(sqlite3_str*); + int (*create_window_function)(sqlite3*,const char*,int,int,void*, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInv)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*)); }; /* @@ -418,7 +442,7 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_rollback_hook sqlite3_api->rollback_hook #define sqlite3_set_authorizer sqlite3_api->set_authorizer #define sqlite3_set_auxdata sqlite3_api->set_auxdata -#define sqlite3_snprintf sqlite3_api->snprintf +#define sqlite3_snprintf sqlite3_api->xsnprintf #define sqlite3_step sqlite3_api->step #define sqlite3_table_column_metadata sqlite3_api->table_column_metadata #define sqlite3_thread_cleanup sqlite3_api->thread_cleanup @@ -558,6 +582,27 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_bind_pointer sqlite3_api->bind_pointer #define sqlite3_result_pointer sqlite3_api->result_pointer #define sqlite3_value_pointer sqlite3_api->value_pointer +/* Version 3.22.0 and later */ +#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange +#define sqlite3_value_nochange sqlite3_api->value_nochange +#define sqlite3_vtab_collation sqlite3_api->vtab_collation +/* Version 3.24.0 and later */ +#define sqlite3_keyword_count sqlite3_api->keyword_count +#define sqlite3_keyword_name sqlite3_api->keyword_name +#define sqlite3_keyword_check sqlite3_api->keyword_check +#define sqlite3_str_new sqlite3_api->str_new +#define sqlite3_str_finish sqlite3_api->str_finish +#define sqlite3_str_appendf sqlite3_api->str_appendf +#define sqlite3_str_vappendf sqlite3_api->str_vappendf +#define sqlite3_str_append sqlite3_api->str_append +#define sqlite3_str_appendall sqlite3_api->str_appendall +#define sqlite3_str_appendchar sqlite3_api->str_appendchar +#define sqlite3_str_reset sqlite3_api->str_reset +#define sqlite3_str_errcode sqlite3_api->str_errcode +#define sqlite3_str_length sqlite3_api->str_length +#define sqlite3_str_value sqlite3_api->str_value +/* Version 3.25.0 and later */ +#define sqlite3_create_window_function sqlite3_api->create_window_function #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a5e19f39ae..bff862e7b6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -50,14 +50,6 @@ # define SQLITE_TCLAPI #endif -/* -** Make sure that rand_s() is available on Windows systems with MSVC 2005 -** or higher. -*/ -#if defined(_MSC_VER) && _MSC_VER>=1400 -# define _CRT_RAND_S -#endif - /* ** Include the header file used to customize the compiler options for MSVC. ** This should be done first so that it can successfully prevent spurious @@ -454,6 +446,21 @@ # define NEVER(X) (X) #endif +/* +** Some conditionals are optimizations only. In other words, if the +** conditionals are replaced with a constant 1 (true) or 0 (false) then +** the correct answer is still obtained, though perhaps not as quickly. +** +** The following macros mark these optimizations conditionals. +*/ +#if defined(SQLITE_MUTATION_TEST) +# define OK_IF_ALWAYS_TRUE(X) (1) +# define OK_IF_ALWAYS_FALSE(X) (0) +#else +# define OK_IF_ALWAYS_TRUE(X) (X) +# define OK_IF_ALWAYS_FALSE(X) (X) +#endif + /* ** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is ** defined. We need to defend against those failures when testing with @@ -630,6 +637,13 @@ # define SQLITE_DEFAULT_PCACHE_INITSZ 20 #endif +/* +** Default value for the SQLITE_CONFIG_SORTERREF_SIZE option. +*/ +#ifndef SQLITE_DEFAULT_SORTERREF_SIZE +# define SQLITE_DEFAULT_SORTERREF_SIZE 0x7fffffff +#endif + /* ** The compile-time options SQLITE_MMAP_READWRITE and ** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another. @@ -777,7 +791,8 @@ typedef INT16_TYPE LogEst; # if defined(__SIZEOF_POINTER__) # define SQLITE_PTRSIZE __SIZEOF_POINTER__ # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(_M_ARM) || defined(__arm__) || defined(__x86) + defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ + (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else # define SQLITE_PTRSIZE 8 @@ -818,7 +833,7 @@ typedef INT16_TYPE LogEst; # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__arm__) + defined(__arm__) || defined(_M_ARM64) # define SQLITE_BYTEORDER 1234 # elif defined(sparc) || defined(__ppc__) # define SQLITE_BYTEORDER 4321 @@ -937,7 +952,7 @@ typedef INT16_TYPE LogEst; ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not ** the Select query generator tracing logic is turned on. */ -#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE) +#if defined(SQLITE_ENABLE_SELECTTRACE) # define SELECTTRACE_ENABLED 1 #else # define SELECTTRACE_ENABLED 0 @@ -954,9 +969,10 @@ typedef INT16_TYPE LogEst; */ typedef struct BusyHandler BusyHandler; struct BusyHandler { - int (*xFunc)(void *,int); /* The busy callback */ - void *pArg; /* First arg to busy callback */ - int nBusy; /* Incremented with each busy call */ + int (*xBusyHandler)(void *,int); /* The busy callback */ + void *pBusyArg; /* First arg to busy callback */ + int nBusy; /* Incremented with each busy call */ + u8 bExtraFileArg; /* Include sqlite3_file as callback arg */ }; /* @@ -1056,7 +1072,6 @@ typedef struct Db Db; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; -typedef struct ExprSpan ExprSpan; typedef struct FKey FKey; typedef struct FuncDestructor FuncDestructor; typedef struct FuncDef FuncDef; @@ -1073,13 +1088,14 @@ typedef struct NameContext NameContext; typedef struct Parse Parse; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; +typedef struct RenameToken RenameToken; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; typedef struct SrcList SrcList; -typedef struct StrAccum StrAccum; +typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; @@ -1088,12 +1104,40 @@ typedef struct Trigger Trigger; typedef struct TriggerPrg TriggerPrg; typedef struct TriggerStep TriggerStep; typedef struct UnpackedRecord UnpackedRecord; +typedef struct Upsert Upsert; typedef struct VTable VTable; typedef struct VtabCtx VtabCtx; typedef struct Walker Walker; typedef struct WhereInfo WhereInfo; +typedef struct Window Window; typedef struct With With; + +/* +** The bitmask datatype defined below is used for various optimizations. +** +** Changing this from a 64-bit to a 32-bit type limits the number of +** tables in a join to 32 instead of 64. But it also reduces the size +** of the library by 738 bytes on ix86. +*/ +#ifdef SQLITE_BITMASK_TYPE + typedef SQLITE_BITMASK_TYPE Bitmask; +#else + typedef u64 Bitmask; +#endif + +/* +** The number of bits in a Bitmask. "BMS" means "BitMask Size". +*/ +#define BMS ((int)(sizeof(Bitmask)*8)) + +/* +** A bit in a Bitmask +*/ +#define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) +#define ALLBITS ((Bitmask)-1) + /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer ** variable number associated with that parameter. See the format description @@ -1217,6 +1261,7 @@ struct Schema { #define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ +#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */ /* ** The number of different kinds of things that can be limited @@ -1248,9 +1293,9 @@ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ - int nOut; /* Number of buffers currently checked out */ - int mxOut; /* Highwater mark for nOut */ - int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + u32 nSlot; /* Number of lookaside slots allocated */ + u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ @@ -1333,6 +1378,7 @@ struct sqlite3 { u32 flags; /* flags settable by pragmas. See below */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 szMmap; /* Default mmap_size setting */ + u32 nSchemaLock; /* Do not reset the schema when non-zero */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ @@ -1349,7 +1395,7 @@ struct sqlite3 { u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ u8 mTrace; /* zero or more SQLITE_TRACE flags */ - u8 skipBtreeMutex; /* True if no shared-cache backends */ + u8 noSharedCache; /* True if no shared-cache backends */ u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ @@ -1361,8 +1407,9 @@ struct sqlite3 { int newTnum; /* Rootpage of table being initialized */ u8 iDb; /* Which db file is being initialized */ u8 busy; /* TRUE if currently initializing */ - u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ - u8 imposterTable; /* Building an imposter table */ + unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ + unsigned imposterTable : 1; /* Building an imposter table */ + unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ @@ -1415,7 +1462,7 @@ struct sqlite3 { Hash aModule; /* populated by sqlite3_create_module() */ VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ VTable **aVTrans; /* Virtual tables with open transactions */ - VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ + VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ #endif Hash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ @@ -1490,7 +1537,11 @@ struct sqlite3 { #define SQLITE_QueryOnly 0x00100000 /* Disable database changes */ #define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */ #define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */ -#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee */ +#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/ +#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */ +#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ +#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ + /* Flags used only if debugging */ #ifdef SQLITE_DEBUG #define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */ @@ -1506,6 +1557,7 @@ struct sqlite3 { #define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */ #define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */ #define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */ +#define DBFLAG_SchemaKnownOk 0x0008 /* Schema is known to be valid */ /* ** Bits of the sqlite3.dbOptFlags field that are used by the @@ -1513,19 +1565,22 @@ struct sqlite3 { ** selectively disable various optimizations. */ #define SQLITE_QueryFlattener 0x0001 /* Query flattening */ -#define SQLITE_ColumnCache 0x0002 /* Column cache */ + /* 0x0002 available for reuse */ #define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ #define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ -/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */ -#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ -#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ -#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ -#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ -#define SQLITE_Transitive 0x0200 /* Transitive constraints */ -#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ +#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x0020 /* Covering index scans */ +#define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */ +#define SQLITE_Transitive 0x0080 /* Transitive constraints */ +#define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */ +#define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */ +#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */ #define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */ -#define SQLITE_CountOfView 0x1000 /* The count-of-view optimization */ -#define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */ + /* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */ +#define SQLITE_PushDown 0x1000 /* The push-down optimization */ +#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ +#define SQLITE_SkipScan 0x4000 /* Skip-scans */ +#define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */ #define SQLITE_AllOpts 0xffff /* All optimizations */ /* @@ -1564,11 +1619,13 @@ struct sqlite3 { */ struct FuncDef { i8 nArg; /* Number of arguments. -1 means unlimited */ - u16 funcFlags; /* Some combination of SQLITE_FUNC_* */ + u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ + void (*xValue)(sqlite3_context*); /* Current agg value */ + void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */ const char *zName; /* SQL name of the function. */ union { FuncDef *pHash; /* Next with a different name but the same hash */ @@ -1624,6 +1681,9 @@ struct FuncDestructor { #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ +#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ +#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */ +#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -1658,6 +1718,12 @@ struct FuncDestructor { ** are interpreted in the same way as the first 4 parameters to ** FUNCTION(). ** +** WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) +** Used to create an aggregate function definition implemented by +** the C functions xStep and xFinal. The first four parameters +** are interpreted in the same way as the first 4 parameters to +** FUNCTION(). +** ** LIKEFUNC(zName, nArg, pArg, flags) ** Used to create a scalar function definition of a function zName ** that accepts nArg arguments and is implemented by a call to C @@ -1668,31 +1734,35 @@ struct FuncDestructor { */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ - 0, 0, xFunc, 0, #zName, {0} } + 0, 0, xFunc, 0, 0, 0, #zName, {0} } #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ - (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} } + (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - pArg, 0, xFunc, 0, #zName, } + pArg, 0, xFunc, 0, 0, 0, #zName, } #define LIKEFUNC(zName, nArg, arg, flags) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ - (void *)arg, 0, likeFunc, 0, #zName, {0} } -#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ + (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } +#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}} + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}} #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}} + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}} + +#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ + {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}} /* ** All current savepoints are stored in a linked list starting at @@ -1748,6 +1818,8 @@ struct Column { #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ #define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ +#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */ +#define COLFLAG_SORTERREF 0x0010 /* Use sorter-refs with this column */ /* ** A "Collating Sequence" is defined by an instance of the following @@ -2035,13 +2107,12 @@ struct FKey { #define OE_Fail 3 /* Stop the operation but leave all prior changes */ #define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ #define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ - -#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ -#define OE_SetNull 7 /* Set the foreign key value to NULL */ -#define OE_SetDflt 8 /* Set the foreign key value to its default */ -#define OE_Cascade 9 /* Cascade the changes */ - -#define OE_Default 10 /* Do whatever the default action is */ +#define OE_Update 6 /* Process as a DO UPDATE in an upsert */ +#define OE_Restrict 7 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ +#define OE_SetNull 8 /* Set the foreign key value to NULL */ +#define OE_SetDflt 9 /* Set the foreign key value to its default */ +#define OE_Cascade 10 /* Cascade the changes */ +#define OE_Default 11 /* Do whatever the default action is */ /* @@ -2168,6 +2239,7 @@ struct Index { unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ + unsigned bNoQuery:1; /* Do not use this index to optimize queries */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ @@ -2176,6 +2248,7 @@ struct Index { tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ #endif + Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */ }; /* @@ -2214,9 +2287,11 @@ struct IndexSample { ** Each token coming out of the lexer is an instance of ** this structure. Tokens are also used as part of an expression. ** -** Note if Token.z==0 then Token.dyn and Token.n are undefined and -** may contain random values. Do not make any assumptions about Token.dyn -** and Token.n when Token.z==0. +** The memory that "z" points to is owned by other objects. Take care +** that the owner of the "z" string does not deallocate the string before +** the Token goes out of scope! Very often, the "z" points to some place +** in the middle of the Parse.zSql text. But it might also point to a +** static string. */ struct Token { const char *z; /* Text of the token. Not NULL-terminated! */ @@ -2389,7 +2464,11 @@ struct Expr { ** TK_COLUMN: the value of p5 for OP_Column ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ - Table *pTab; /* Table for TK_COLUMN expressions. */ + union { + Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL + ** for a column of an index on an expression */ + Window *pWin; /* TK_FUNCTION: Window definition for the func */ + } y; }; /* @@ -2397,8 +2476,8 @@ struct Expr { */ #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ - /* 0x000004 // available for use */ - /* 0x000008 // available for use */ +#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ +#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ @@ -2419,11 +2498,13 @@ struct Expr { #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ #define EP_Alias 0x400000 /* Is an alias for a result set column */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ +#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ /* -** Combinations of two or more EP_* flags +** The EP_Propagate mask is a set of properties that automatically propagate +** upwards into parent nodes. */ -#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ +#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) /* ** These macros can be used to test, set, or clear bits in the @@ -2477,7 +2558,6 @@ struct Expr { */ struct ExprList { int nExpr; /* Number of expressions on the list */ - int nAlloc; /* Number of a[] slots allocated */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ @@ -2486,6 +2566,7 @@ struct ExprList { unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ unsigned reusable :1; /* Constant expression is reusable */ + unsigned bSorterRef :1; /* Defer evaluation until after sorting */ union { struct { u16 iOrderByCol; /* For ORDER BY, column number in result set */ @@ -2496,17 +2577,6 @@ struct ExprList { } a[1]; /* One slot for each expression in the list */ }; -/* -** An instance of this structure is used by the parser to record both -** the parse tree for an expression and the span of input text for an -** expression. -*/ -struct ExprSpan { - Expr *pExpr; /* The expression parse tree */ - const char *zStart; /* First character of input text */ - const char *zEnd; /* One character past the end of input text */ -}; - /* ** An instance of this structure can hold a simple list of identifiers, ** such as the list "a,b,c" in the following statements: @@ -2530,31 +2600,6 @@ struct IdList { int nId; /* Number of identifiers on the list */ }; -/* -** The bitmask datatype defined below is used for various optimizations. -** -** Changing this from a 64-bit to a 32-bit type limits the number of -** tables in a join to 32 instead of 64. But it also reduces the size -** of the library by 738 bytes on ix86. -*/ -#ifdef SQLITE_BITMASK_TYPE - typedef SQLITE_BITMASK_TYPE Bitmask; -#else - typedef u64 Bitmask; -#endif - -/* -** The number of bits in a Bitmask. "BMS" means "BitMask Size". -*/ -#define BMS ((int)(sizeof(Bitmask)*8)) - -/* -** A bit in a Bitmask -*/ -#define MASKBIT(n) (((Bitmask)1)<<(n)) -#define MASKBIT32(n) (((unsigned int)1)<<(n)) -#define ALLBITS ((Bitmask)-1) - /* ** The following structure describes the FROM clause of a SELECT statement. ** Each table or subquery in the FROM clause is a separate element of @@ -2596,9 +2641,6 @@ struct SrcList { unsigned viaCoroutine :1; /* Implemented as a co-routine */ unsigned isRecursive :1; /* True for recursive reference in WITH */ } fg; -#ifndef SQLITE_OMIT_EXPLAIN - u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ -#endif int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ IdList *pUsing; /* The USING clause of a join */ @@ -2680,12 +2722,16 @@ struct SrcList { struct NameContext { Parse *pParse; /* The parser */ SrcList *pSrcList; /* One or more tables used to resolve names */ - ExprList *pEList; /* Optional list of result-set columns */ - AggInfo *pAggInfo; /* Information about aggregates at this level */ + union { + ExprList *pEList; /* Optional list of result-set columns */ + AggInfo *pAggInfo; /* Information about aggregates at this level */ + Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */ + } uNC; NameContext *pNext; /* Next outer name context. NULL for outermost */ int nRef; /* Number of names resolved by this context */ int nErr; /* Number of errors encountered while resolving names */ u16 ncFlags; /* Zero or more NC_* flags defined below */ + Select *pWinSelect; /* SELECT statement for any window functions */ }; /* @@ -2703,17 +2749,49 @@ struct NameContext { #define NC_HasAgg 0x0010 /* One or more aggregate functions seen */ #define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */ #define NC_VarSelect 0x0040 /* A correlated subquery has been seen */ +#define NC_UEList 0x0080 /* True if uNC.pEList is used */ +#define NC_UAggInfo 0x0100 /* True if uNC.pAggInfo is used */ +#define NC_UUpsert 0x0200 /* True if uNC.pUpsert is used */ #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ +#define NC_Complex 0x2000 /* True if a function or subquery seen */ +#define NC_AllowWin 0x4000 /* Window functions are allowed here */ + +/* +** An instance of the following object describes a single ON CONFLICT +** clause in an upsert. +** +** The pUpsertTarget field is only set if the ON CONFLICT clause includes +** conflict-target clause. (In "ON CONFLICT(a,b)" the "(a,b)" is the +** conflict-target clause.) The pUpsertTargetWhere is the optional +** WHERE clause used to identify partial unique indexes. +** +** pUpsertSet is the list of column=expr terms of the UPDATE statement. +** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING. The +** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the +** WHERE clause is omitted. +*/ +struct Upsert { + ExprList *pUpsertTarget; /* Optional description of conflicting index */ + Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ + ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ + Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ + /* The fields above comprise the parse tree for the upsert clause. + ** The fields below are used to transfer information from the INSERT + ** processing down into the UPDATE processing while generating code. + ** Upsert owns the memory allocated above, but not the memory below. */ + Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */ + SrcList *pUpsertSrc; /* Table to be updated */ + int regData; /* First register holding array of VALUES */ + int iDataCur; /* Index of the data cursor */ + int iIdxCur; /* Index of the first index cursor */ +}; /* ** An instance of the following structure contains all information ** needed to generate code for a single SELECT statement. ** -** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0. -** If there is a LIMIT clause, the parser sets nLimit to the value of the -** limit and nOffset to the value of the offset (or 0 if there is not -** offset). But later on, nLimit and nOffset become the memory locations -** in the VDBE that record the limit and offset counters. +** See the header comment on the computeLimitRegisters() routine for a +** detailed description of the meaning of the iLimit and iOffset fields. ** ** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes. ** These addresses must be stored so that we can go back and fill in @@ -2731,9 +2809,7 @@ struct Select { LogEst nSelectRow; /* Estimated number of result rows */ u32 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ -#if SELECTTRACE_ENABLED - char zSelName[12]; /* Symbolic name of this SELECT use for debugging */ -#endif + u32 selId; /* Unique identifier number for this SELECT */ int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ SrcList *pSrc; /* The FROM clause */ Expr *pWhere; /* The WHERE clause */ @@ -2743,8 +2819,11 @@ struct Select { Select *pPrior; /* Prior select in a compound select statement */ Select *pNext; /* Next select to the left in a compound */ Expr *pLimit; /* LIMIT expression. NULL means not used. */ - Expr *pOffset; /* OFFSET expression. NULL means not used. */ With *pWith; /* WITH clause attached to this select. Or NULL. */ +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin; /* List of window functions */ + Window *pWinDefn; /* List of named window definitions */ +#endif }; /* @@ -2774,7 +2853,7 @@ struct Select { #define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ #define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ - +#define SF_ComplexResult 0x40000 /* Result contains subquery or function */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -2888,13 +2967,6 @@ struct AutoincInfo { int regCtr; /* Memory register holding the rowid counter */ }; -/* -** Size of the column cache -*/ -#ifndef SQLITE_N_COLCACHE -# define SQLITE_N_COLCACHE 10 -#endif - /* ** At least one instance of the following structure is created for each ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE @@ -2970,7 +3042,6 @@ struct Parse { u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ - u8 nColCache; /* Number of entries in aColCache[] */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ @@ -2978,10 +3049,8 @@ struct Parse { int nMem; /* Number of memory cells used so far */ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ - int iSelfTab; /* Table for associated with an index on expr, or negative + int iSelfTab; /* Table associated with an index on expr, or negative ** of the base register during check-constraint eval */ - int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ - int iCacheCnt; /* Counter used to generate aColCache[].lru values */ int nLabel; /* Number of labels used */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ @@ -2991,10 +3060,7 @@ struct Parse { int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ -#if SELECTTRACE_ENABLED - int nSelect; /* Number of SELECT statements seen */ - int nSelectIndent; /* How far to indent SELECTTRACE() output */ -#endif + int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ @@ -3002,7 +3068,7 @@ struct Parse { AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ 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 addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */ u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ @@ -3014,17 +3080,9 @@ struct Parse { ** Fields above must be initialized to zero. The fields that follow, ** down to the beginning of the recursive section, do not need to be ** initialized as they will be set before being used. The boundary is - ** determined by offsetof(Parse,aColCache). + ** determined by offsetof(Parse,aTempReg). **************************************************************************/ - struct yColCache { - int iTable; /* Table cursor number */ - i16 iColumn; /* Table column number */ - u8 tempReg; /* iReg is a temp register that needs to be freed */ - int iLevel; /* Nesting level */ - int iReg; /* Reg with value of this column. 0 means none. */ - int lru; /* Least recently used entry has the smallest value */ - } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ int aTempReg[8]; /* Holding area for temporary registers */ Token sNameToken; /* Token with unqualified schema object name */ @@ -3039,19 +3097,21 @@ struct Parse { ynVar nVar; /* Number of '?' variables seen in the SQL so far */ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ u8 explain; /* True if the EXPLAIN flag is found on the query */ +#if !(defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)) + u8 eParseMode; /* PARSE_MODE_XXX constant */ +#endif #ifndef SQLITE_OMIT_VIRTUALTABLE - u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ int nVtabLock; /* Number of virtual tables to lock */ #endif int nHeight; /* Expression tree height of current sub-select */ #ifndef SQLITE_OMIT_EXPLAIN - int iSelectId; /* ID of current select for EXPLAIN output */ - int iNextSelectId; /* Next available select ID for EXPLAIN output */ + int addrExplain; /* Address of current OP_Explain opcode */ #endif VList *pVList; /* Mapping between variable names and numbers */ Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ + Index *pNewIndex; /* An index being constructed by CREATE INDEX */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -3062,12 +3122,20 @@ struct Parse { TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ With *pWithToFree; /* Free this WITH object at the end of the parse */ +#ifndef SQLITE_OMIT_ALTERTABLE + RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ +#endif }; +#define PARSE_MODE_NORMAL 0 +#define PARSE_MODE_DECLARE_VTAB 1 +#define PARSE_MODE_RENAME_COLUMN 2 +#define PARSE_MODE_RENAME_TABLE 3 + /* ** Sizes and pointers of various parts of the Parse object. */ -#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/ +#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/ #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */ #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ @@ -3078,7 +3146,19 @@ struct Parse { #ifdef SQLITE_OMIT_VIRTUALTABLE #define IN_DECLARE_VTAB 0 #else - #define IN_DECLARE_VTAB (pParse->declareVtab) + #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB) +#endif + +#if defined(SQLITE_OMIT_ALTERTABLE) + #define IN_RENAME_OBJECT 0 +#else + #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN) +#endif + +#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE) + #define IN_SPECIAL_PARSE 0 +#else + #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL) #endif /* @@ -3104,6 +3184,7 @@ struct AuthContext { */ #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ /* Also used in P2 (not P5) of OP_Delete */ +#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */ #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ #define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */ #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ @@ -3119,6 +3200,7 @@ struct AuthContext { #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ +#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ /* * Each trigger present in the database schema is stored as an instance of @@ -3204,8 +3286,10 @@ struct TriggerStep { Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ - ExprList *pExprList; /* SET clause for UPDATE. */ + ExprList *pExprList; /* SET clause for UPDATE */ IdList *pIdList; /* Column names for INSERT */ + Upsert *pUpsert; /* Upsert clauses on an INSERT */ + char *zSpan; /* Original SQL text of this command */ TriggerStep *pNext; /* Next in the link-list */ TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ }; @@ -3229,18 +3313,15 @@ struct DbFixer { ** An objected used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. */ -struct StrAccum { +struct sqlite3_str { sqlite3 *db; /* Optional database for lookaside. Can be NULL */ - char *zBase; /* A base allocation. Not from malloc. */ char *zText; /* The string collected so far */ - u32 nChar; /* Length of the string so far */ u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ - u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ + u32 nChar; /* Length of the string so far */ + u8 accError; /* SQLITE_NOMEM or SQLITE_TOOBIG */ u8 printfFlags; /* SQLITE_PRINTF flags below */ }; -#define STRACCUM_NOMEM 1 -#define STRACCUM_TOOBIG 2 #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ #define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ @@ -3257,8 +3338,14 @@ typedef struct { char **pzErrMsg; /* Error message stored here */ int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ int rc; /* Result code stored here */ + u32 mInitFlags; /* Flags controlling error messages */ } InitData; +/* +** Allowed values for mInitFlags +*/ +#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ + /* ** Structure containing global configuration data for the SQLite library. ** @@ -3270,6 +3357,7 @@ struct Sqlite3Config { int bFullMutex; /* True to enable full mutexing */ int bOpenUri; /* True to interpret filenames as URIs */ int bUseCis; /* Use covering indices for full-scans */ + int bSmallMalloc; /* Avoid large memory allocations if true */ int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ @@ -3283,9 +3371,6 @@ struct Sqlite3Config { int mnReq, mxReq; /* Min and max heap requests sizes */ sqlite3_int64 szMmap; /* mmap() space per open file */ sqlite3_int64 mxMmap; /* Maximum value for szMmap */ - void *pScratch; /* Scratch memory */ - int szScratch; /* Size of each scratch buffer */ - int nScratch; /* Number of scratch buffers */ void *pPage; /* Page cache memory */ int szPage; /* Size of each page in pPage[] */ int nPage; /* Number of pages in pPage[] */ @@ -3311,7 +3396,7 @@ struct Sqlite3Config { /* The following callback (if not NULL) is invoked on every VDBE branch ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. */ - void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ + void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */ void *pVdbeBranchArg; /* 1st argument */ #endif #ifndef SQLITE_UNTESTABLE @@ -3319,6 +3404,7 @@ struct Sqlite3Config { #endif int bLocaltimeFault; /* True to fail localtime() calls */ int iOnceResetThreshold; /* When to reset OP_Once counters */ + u32 szSorterRef; /* Min size in bytes to use sorter-refs */ }; /* @@ -3358,9 +3444,12 @@ struct Walker { struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ int *aiCol; /* array of column indexes */ struct IdxCover *pIdxCover; /* Check for index coverage */ - struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */ + struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ ExprList *pGroupBy; /* GROUP BY clause */ - struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */ + Select *pSelect; /* HAVING to WHERE clause ctx */ + struct WindowRewrite *pRewrite; /* Window rewrite context */ + struct WhereConst *pConst; /* WHERE clause constants */ + struct RenameCtx *pRename; /* RENAME COLUMN context */ } u; }; @@ -3372,6 +3461,7 @@ int sqlite3WalkSelectExpr(Walker*, Select*); int sqlite3WalkSelectFrom(Walker*, Select*); int sqlite3ExprWalkNoop(Walker*, Expr*); int sqlite3SelectWalkNoop(Walker*, Select*); +int sqlite3SelectWalkFail(Walker*, Select*); #ifdef SQLITE_DEBUG void sqlite3SelectWalkAssert2(Walker*, Select*); #endif @@ -3410,6 +3500,68 @@ struct TreeView { }; #endif /* SQLITE_DEBUG */ +/* +** This object is used in varioius ways, all related to window functions +** +** (1) A single instance of this structure is attached to the +** the Expr.pWin field for each window function in an expression tree. +** This object holds the information contained in the OVER clause, +** plus additional fields used during code generation. +** +** (2) All window functions in a single SELECT form a linked-list +** attached to Select.pWin. The Window.pFunc and Window.pExpr +** fields point back to the expression that is the window function. +** +** (3) The terms of the WINDOW clause of a SELECT are instances of this +** object on a linked list attached to Select.pWinDefn. +** +** The uses (1) and (2) are really the same Window object that just happens +** to be accessible in two different ways. Use (3) is are separate objects. +*/ +struct Window { + char *zName; /* Name of window (may be NULL) */ + ExprList *pPartition; /* PARTITION BY clause */ + ExprList *pOrderBy; /* ORDER BY clause */ + u8 eType; /* TK_RANGE or TK_ROWS */ + u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ + u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ + Expr *pStart; /* Expression for " PRECEDING" */ + Expr *pEnd; /* Expression for " FOLLOWING" */ + Window *pNextWin; /* Next window function belonging to this SELECT */ + Expr *pFilter; /* The FILTER expression */ + FuncDef *pFunc; /* The function */ + int iEphCsr; /* Partition buffer or Peer buffer */ + int regAccum; + int regResult; + int csrApp; /* Function cursor (used by min/max) */ + int regApp; /* Function register (also used by min/max) */ + int regPart; /* First in a set of registers holding PARTITION BY + ** and ORDER BY values for the window */ + Expr *pOwner; /* Expression object this window is attached to */ + int nBufferCol; /* Number of columns in buffer table */ + int iArgCol; /* Offset of first argument for this function */ +}; + +#ifndef SQLITE_OMIT_WINDOWFUNC +void sqlite3WindowDelete(sqlite3*, Window*); +void sqlite3WindowListDelete(sqlite3 *db, Window *p); +Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*); +void sqlite3WindowAttach(Parse*, Expr*, Window*); +int sqlite3WindowCompare(Parse*, Window*, Window*); +void sqlite3WindowCodeInit(Parse*, Window*); +void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); +int sqlite3WindowRewrite(Parse*, Select*); +int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); +void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); +Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); +Window *sqlite3WindowListDup(sqlite3 *db, Window *p); +void sqlite3WindowFunctions(void); +#else +# define sqlite3WindowDelete(a,b) +# define sqlite3WindowFunctions() +# define sqlite3WindowAttach(a,b,c) +#endif + /* ** Assuming zIn points to the first byte of a UTF-8 character, ** advance zIn to point to the first byte of the next UTF-8 character. @@ -3427,6 +3579,7 @@ struct TreeView { ** using sqlite3_log(). The routines also provide a convenient place ** to set a debugger breakpoint. */ +int sqlite3ReportError(int iErr, int lineno, const char *zType); int sqlite3CorruptError(int); int sqlite3MisuseError(int); int sqlite3CantopenError(int); @@ -3496,9 +3649,7 @@ int sqlite3CantopenError(int); # define sqlite3Tolower(x) tolower((unsigned char)(x)) # define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') #endif -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS int sqlite3IsIdChar(u8); -#endif /* ** Internal function prototypes @@ -3517,6 +3668,7 @@ void *sqlite3DbMallocRaw(sqlite3*, u64); void *sqlite3DbMallocRawNN(sqlite3*, u64); char *sqlite3DbStrDup(sqlite3*,const char*); char *sqlite3DbStrNDup(sqlite3*,const char*, u64); +char *sqlite3DbSpanDup(sqlite3*,const char*,const char*); void *sqlite3Realloc(void*, u64); void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); void *sqlite3DbRealloc(sqlite3 *, void *, u64); @@ -3524,8 +3676,6 @@ void sqlite3DbFree(sqlite3*, void*); void sqlite3DbFreeNN(sqlite3*, void*); int sqlite3MallocSize(void*); int sqlite3DbMallocSize(sqlite3*, void*); -void *sqlite3ScratchMalloc(int); -void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); @@ -3581,11 +3731,18 @@ sqlite3_int64 sqlite3StatusValue(int); void sqlite3StatusUp(int, int); void sqlite3StatusDown(int, int); void sqlite3StatusHighwater(int, int); +int sqlite3LookasideUsed(sqlite3*,int*); /* Access to mutexes used by sqlite3_status() */ sqlite3_mutex *sqlite3Pcache1Mutex(void); sqlite3_mutex *sqlite3MallocMutex(void); +#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT) +void sqlite3MutexWarnOnContention(sqlite3_mutex*); +#else +# define sqlite3MutexWarnOnContention(x) +#endif + #ifndef SQLITE_OMIT_FLOATING_POINT int sqlite3IsNaN(double); #else @@ -3602,8 +3759,6 @@ struct PrintfArguments { sqlite3_value **apArg; /* The argument values */ }; -void sqlite3VXPrintf(StrAccum*, const char*, va_list); -void sqlite3XPrintf(StrAccum*, const char*, ...); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) @@ -3619,6 +3774,10 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); +#ifndef SQLITE_OMIT_WINDOWFUNC + void sqlite3TreeViewWindow(TreeView*, const Window*, u8); + void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); +#endif #endif @@ -3643,18 +3802,19 @@ void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); -Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); +Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); void sqlite3ExprListSetSortOrder(ExprList*,int); void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); -void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); +void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); void sqlite3ExprListDelete(sqlite3*, ExprList*); u32 sqlite3ExprListFlags(const ExprList*); int sqlite3Init(sqlite3*, char**); int sqlite3InitCallback(void*, int, char**, char**); +int sqlite3InitOne(sqlite3*, int, char**, u32); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); #ifndef SQLITE_OMIT_VIRTUALTABLE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); @@ -3680,7 +3840,7 @@ void sqlite3AddColumn(Parse*,Token*,Token*); void sqlite3AddNotNull(Parse*, int); void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); void sqlite3AddCheckConstraint(Parse*, Expr*); -void sqlite3AddDefaultValue(Parse*,ExprSpan*); +void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, @@ -3704,8 +3864,9 @@ u32 sqlite3BitvecSize(Bitvec*); int sqlite3BitvecBuiltinTest(int,int*); #endif -RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); -void sqlite3RowSetClear(RowSet*); +RowSet *sqlite3RowSetInit(sqlite3*); +void sqlite3RowSetDelete(void*); +void sqlite3RowSetClear(void*); void sqlite3RowSetInsert(RowSet*, i64); int sqlite3RowSetTest(RowSet*, int iBatch, i64); int sqlite3RowSetNext(RowSet*, i64*); @@ -3724,6 +3885,7 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); void sqlite3DropTable(Parse*, SrcList*, int, int); void sqlite3CodeDropTable(Parse*, Table*, int, int); void sqlite3DeleteTable(sqlite3*, Table*); +void sqlite3FreeIndex(sqlite3*, Index*); #ifndef SQLITE_OMIT_AUTOINCREMENT void sqlite3AutoincrementBegin(Parse *pParse); void sqlite3AutoincrementEnd(Parse *pParse); @@ -3731,9 +3893,9 @@ void sqlite3DeleteTable(sqlite3*, Table*); # define sqlite3AutoincrementBegin(X) # define sqlite3AutoincrementEnd(X) #endif -void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int); +void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); -IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); +IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); int sqlite3IdListIndex(IdList*,const char*); SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); @@ -3752,22 +3914,23 @@ void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, - Expr*,ExprList*,u32,Expr*,Expr*); + Expr*,ExprList*,u32,Expr*); void sqlite3SelectDelete(sqlite3*, Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) -Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*); +Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif -void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); -void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); +void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); +void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, + Upsert*); WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); void sqlite3WhereEnd(WhereInfo*); LogEst sqlite3WhereOutputRowCount(WhereInfo*); int sqlite3WhereIsDistinct(WhereInfo*); int sqlite3WhereIsOrdered(WhereInfo*); -int sqlite3WhereOrderedInnerLoop(WhereInfo*); +int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); int sqlite3WhereIsSorted(WhereInfo*); int sqlite3WhereContinueLabel(WhereInfo*); int sqlite3WhereBreakLabel(WhereInfo*); @@ -3777,15 +3940,8 @@ int sqlite3WhereOkOnePass(WhereInfo*, int*); #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); -void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int); void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int, int); -void sqlite3ExprCacheStore(Parse*, int, int, int); -void sqlite3ExprCachePush(Parse*); -void sqlite3ExprCachePop(Parse*); -void sqlite3ExprCacheRemove(Parse*, int, int); -void sqlite3ExprCacheClear(Parse*); -void sqlite3ExprCacheAffinityChange(Parse*, int, int); void sqlite3ExprCode(Parse*, Expr*, int); void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); @@ -3816,6 +3972,7 @@ int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); int sqlite3ExprCompareSkip(Expr*, Expr*, int); int sqlite3ExprListCompare(ExprList*, ExprList*, int); int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); +int sqlite3ExprImpliesNonNullRow(Expr*,int); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); @@ -3833,6 +3990,8 @@ void sqlite3EndTransaction(Parse*,int); void sqlite3Savepoint(Parse*, int, Token*); void sqlite3CloseSavepoints(sqlite3 *); void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +int sqlite3ExprIdToTrueFalse(Expr*); +int sqlite3ExprTruthValue(const Expr*); int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*, u8); @@ -3850,8 +4009,9 @@ void sqlite3GenerateRowDelete( void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); void sqlite3ResolvePartIdxLabel(Parse*,int); +int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, - u8,u8,int,int*,int*); + u8,u8,int,int*,int*,Upsert*); #ifdef SQLITE_ENABLE_NULL_TRIM void sqlite3SetMakeRecordP5(Vdbe*,Table*); #else @@ -3870,11 +4030,6 @@ ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); IdList *sqlite3IdListDup(sqlite3*,IdList*); Select *sqlite3SelectDup(sqlite3*,Select*,int); -#if SELECTTRACE_ENABLED -void sqlite3SelectSetName(Select*,const char*); -#else -# define sqlite3SelectSetName(A,B) -#endif void sqlite3InsertBuiltinFuncs(FuncDef*,int); FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); void sqlite3RegisterBuiltinFunctions(void); @@ -3885,7 +4040,7 @@ int sqlite3SafetyCheckSickOrOk(sqlite3*); void sqlite3ChangeCookie(Parse*, int); #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) -void sqlite3MaterializeView(Parse*, Table*, Expr*, int); +void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif #ifndef SQLITE_OMIT_TRIGGER @@ -3901,11 +4056,15 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, int); void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); - TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*); - TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, - Select*,u8); - TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8); - TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*); + TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, + const char*,const char*); + TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*, + Select*,u8,Upsert*, + const char*,const char*); + TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8, + const char*,const char*); + TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*, + const char*,const char*); void sqlite3DeleteTrigger(sqlite3*, Trigger*); void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); @@ -4012,11 +4171,18 @@ int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); const char *sqlite3ErrName(int); #endif +#ifdef SQLITE_ENABLE_DESERIALIZE +int sqlite3MemdbInit(void); +#endif + const char *sqlite3ErrStr(int); int sqlite3ReadSchema(Parse *pParse); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); +int sqlite3IsBinary(const CollSeq*); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); +CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr); +int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*); Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); Expr *sqlite3ExprSkipCollate(Expr*); @@ -4058,13 +4224,17 @@ extern FuncDefHash sqlite3BuiltinFunctions; extern int sqlite3PendingByte; #endif #endif +#ifdef VDBE_PROFILE +extern sqlite3_uint64 sqlite3NProfileCnt; +#endif void sqlite3RootPageMoved(sqlite3*, int, int, int); void sqlite3Reindex(Parse*, Token*, Token*); void sqlite3AlterFunctions(void); void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); +void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); -void sqlite3ExpirePreparedStatements(sqlite3*); +void sqlite3ExpirePreparedStatements(sqlite3*, int); int sqlite3CodeSubselect(Parse*, Expr *, int, int); void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); @@ -4077,10 +4247,14 @@ int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); void sqlite3ColumnDefault(Vdbe *, Table *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +void *sqlite3RenameTokenMap(Parse*, void*, Token*); +void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); +void sqlite3RenameExprUnmap(Parse*, Expr*); +void sqlite3RenameExprlistUnmap(Parse*, ExprList*); CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); -char sqlite3AffinityType(const char*, u8*); +char sqlite3AffinityType(const char*, Column*); void sqlite3Analyze(Parse*, Token*, Token*); -int sqlite3InvokeBusyHandler(BusyHandler*); +int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*); int sqlite3FindDb(sqlite3*, Token*); int sqlite3FindDbName(sqlite3 *, const char *); int sqlite3AnalysisLoad(sqlite3*,int iDB); @@ -4098,25 +4272,27 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); void sqlite3KeyInfoUnref(KeyInfo*); KeyInfo *sqlite3KeyInfoRef(KeyInfo*); KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); +KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); + #ifdef SQLITE_DEBUG int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), - void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*,int,sqlite3_value **), FuncDestructor *pDestructor ); +void sqlite3NoopDestructor(void*); void sqlite3OomFault(sqlite3*); void sqlite3OomClear(sqlite3*); int sqlite3ApiExit(sqlite3 *db, int); int sqlite3OpenTempDatabase(Parse *); void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); -void sqlite3StrAccumAppend(StrAccum*,const char*,int); -void sqlite3StrAccumAppendAll(StrAccum*,const char*); -void sqlite3AppendChar(StrAccum*,int,char); char *sqlite3StrAccumFinish(StrAccum*); -void sqlite3StrAccumReset(StrAccum*); void sqlite3SelectDestInit(SelectDest*,int,int); Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); @@ -4143,10 +4319,11 @@ char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); ** The interface to the LEMON-generated parser */ #ifndef SQLITE_AMALGAMATION - void *sqlite3ParserAlloc(void*(*)(u64)); + void *sqlite3ParserAlloc(void*(*)(u64), Parse*); void sqlite3ParserFree(void*, void(*)(void*)); #endif -void sqlite3Parser(void*, int, Token, Parse*); +void sqlite3Parser(void*, int, Token); +int sqlite3ParserFallback(int); #ifdef YYTRACKMAXSTACKDEPTH int sqlite3ParserStackPeak(void*); #endif @@ -4212,7 +4389,6 @@ int sqlite3VtabCallConnect(Parse*, Table*); int sqlite3VtabCallDestroy(sqlite3*, int, const char *); int sqlite3VtabBegin(sqlite3 *, VTable *); FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); -void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); @@ -4234,6 +4410,18 @@ const char *sqlite3JournalModename(int); #define sqlite3WithPush(x,y,z) #define sqlite3WithDelete(x,y) #endif +#ifndef SQLITE_OMIT_UPSERT + Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); + void sqlite3UpsertDelete(sqlite3*,Upsert*); + Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); + int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); + void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); +#else +#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0) +#define sqlite3UpsertDelete(x,y) +#define sqlite3UpsertDup(x,y) ((Upsert*)0) +#endif + /* Declarations for functions in fkey.c. All of these are replaced by ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign @@ -4336,6 +4524,9 @@ void sqlite3Put4byte(u8*, u32); #ifdef SQLITE_DEBUG void sqlite3ParserTrace(FILE*, char *); #endif +#if defined(YYCOVERAGE) + int sqlite3ParserCoverage(FILE*); +#endif /* ** If the SQLITE_ENABLE IOTRACE exists then the global variable @@ -4390,8 +4581,7 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ -#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ -#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ +#define MEMTYPE_PCACHE 0x04 /* Page cache allocations */ /* ** Threading interface @@ -4401,6 +4591,9 @@ int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); int sqlite3ThreadJoin(SQLiteThread*, void**); #endif +#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST) +int sqlite3DbpageRegister(sqlite3*); +#endif #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST) int sqlite3DbstatRegister(sqlite3*); #endif diff --git a/src/status.c b/src/status.c index 24dcad4572..a5a39f4c18 100644 --- a/src/status.c +++ b/src/status.c @@ -122,7 +122,6 @@ void sqlite3StatusHighwater(int op, int X){ : sqlite3MallocMutex()) ); assert( op==SQLITE_STATUS_MALLOC_SIZE || op==SQLITE_STATUS_PAGECACHE_SIZE - || op==SQLITE_STATUS_SCRATCH_SIZE || op==SQLITE_STATUS_PARSER_STACK ); if( newValue>wsdStat.mxValue[op] ){ wsdStat.mxValue[op] = newValue; @@ -171,6 +170,28 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ return rc; } +/* +** Return the number of LookasideSlot elements on the linked list +*/ +static u32 countLookasideSlots(LookasideSlot *p){ + u32 cnt = 0; + while( p ){ + p = p->pNext; + cnt++; + } + return cnt; +} + +/* +** Count the number of slots of lookaside memory that are outstanding +*/ +int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ + u32 nInit = countLookasideSlots(db->lookaside.pInit); + u32 nFree = countLookasideSlots(db->lookaside.pFree); + if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit; + return db->lookaside.nSlot - (nInit+nFree); +} + /* ** Query status information for a single database connection */ @@ -190,10 +211,15 @@ int sqlite3_db_status( sqlite3_mutex_enter(db->mutex); switch( op ){ case SQLITE_DBSTATUS_LOOKASIDE_USED: { - *pCurrent = db->lookaside.nOut; - *pHighwater = db->lookaside.mxOut; + *pCurrent = sqlite3LookasideUsed(db, pHighwater); if( resetFlag ){ - db->lookaside.mxOut = db->lookaside.nOut; + LookasideSlot *p = db->lookaside.pFree; + if( p ){ + while( p->pNext ) p = p->pNext; + p->pNext = db->lookaside.pInit; + db->lookaside.pInit = db->lookaside.pFree; + db->lookaside.pFree = 0; + } } break; } @@ -311,6 +337,9 @@ int sqlite3_db_status( ** pagers the database handle is connected to. *pHighwater is always set ** to zero. */ + case SQLITE_DBSTATUS_CACHE_SPILL: + op = SQLITE_DBSTATUS_CACHE_WRITE+1; + /* Fall through into the next case */ case SQLITE_DBSTATUS_CACHE_HIT: case SQLITE_DBSTATUS_CACHE_MISS: case SQLITE_DBSTATUS_CACHE_WRITE:{ diff --git a/src/tclsqlite.c b/src/tclsqlite.c index dbed46a437..fb751e3912 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -14,17 +14,19 @@ ** ** Compile-time options: ** -** -DTCLSH=1 Add a "main()" routine that works as a tclsh. +** -DTCLSH Add a "main()" routine that works as a tclsh. ** -** -DSQLITE_TCLMD5 When used in conjuction with -DTCLSH=1, add -** four new commands to the TCL interpreter for -** generating MD5 checksums: md5, md5file, -** md5-10x8, and md5file-10x8. +** -DTCLSH_INIT_PROC=name ** -** -DSQLITE_TEST When used in conjuction with -DTCLSH=1, add -** hundreds of new commands used for testing -** SQLite. This option implies -DSQLITE_TCLMD5. +** Invoke name(interp) to initialize the Tcl interpreter. +** If name(interp) returns a non-NULL string, then run +** that string as a Tcl script to launch the application. +** If name(interp) returns NULL, then run the regular +** tclsh-emulator code. */ +#ifdef TCLSH_INIT_PROC +# define TCLSH 1 +#endif /* ** If requested, include the SQLite compiler options file for MSVC. @@ -58,13 +60,18 @@ /* Used to get the current process ID */ #if !defined(_WIN32) +# include # include # define GETPID getpid #elif !defined(_WIN32_WCE) # ifndef SQLITE_AMALGAMATION -# define WIN32_LEAN_AND_MEAN +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif # include # endif +# include +# define isatty(h) _isatty(h) # define GETPID (int)GetCurrentProcessId #endif @@ -644,7 +651,7 @@ static int DbTraceV2Handler( } case SQLITE_TRACE_PROFILE: { sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; - sqlite3_int64 ns = (sqlite3_int64)xd; + sqlite3_int64 ns = *(sqlite3_int64*)xd; pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); Tcl_IncrRefCount(pCmd); @@ -1844,35 +1851,35 @@ static int SQLITE_TCLAPI DbObjCmd( int choice; int rc = TCL_OK; static const char *DB_strs[] = { - "authorizer", "backup", "busy", - "cache", "changes", "close", - "collate", "collation_needed", "commit_hook", - "complete", "copy", "enable_load_extension", - "errorcode", "eval", "exists", - "function", "incrblob", "interrupt", - "last_insert_rowid", "nullvalue", "onecolumn", - "preupdate", "profile", "progress", - "rekey", "restore", "rollback_hook", - "status", "timeout", "total_changes", - "trace", "trace_v2", "transaction", - "unlock_notify", "update_hook", "version", - "wal_hook", - 0 + "authorizer", "backup", "busy", + "cache", "changes", "close", + "collate", "collation_needed", "commit_hook", + "complete", "copy", "deserialize", + "enable_load_extension", "errorcode", "eval", + "exists", "function", "incrblob", + "interrupt", "last_insert_rowid", "nullvalue", + "onecolumn", "preupdate", "profile", + "progress", "rekey", "restore", + "rollback_hook", "serialize", "status", + "timeout", "total_changes", "trace", + "trace_v2", "transaction", "unlock_notify", + "update_hook", "version", "wal_hook", + 0 }; enum DB_enum { - DB_AUTHORIZER, DB_BACKUP, DB_BUSY, - DB_CACHE, DB_CHANGES, DB_CLOSE, - DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, - DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION, - DB_ERRORCODE, DB_EVAL, DB_EXISTS, - DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, - DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, - DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, - DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, - DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, - DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, - DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, - DB_WAL_HOOK, + DB_AUTHORIZER, DB_BACKUP, DB_BUSY, + DB_CACHE, DB_CHANGES, DB_CLOSE, + DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, + DB_COMPLETE, DB_COPY, DB_DESERIALIZE, + DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL, + DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, + DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, + DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE, + DB_PROGRESS, DB_REKEY, DB_RESTORE, + DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS, + DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, + DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY, + DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2410,6 +2417,53 @@ static int SQLITE_TCLAPI DbObjCmd( break; } + /* + ** $db deserialize ?DATABASE? VALUE + ** + ** Reopen DATABASE (default "main") using the content in $VALUE + */ + case DB_DESERIALIZE: { +#ifndef SQLITE_ENABLE_DESERIALIZE + Tcl_AppendResult(interp, "MEMDB not available in this build", + (char*)0); + rc = TCL_ERROR; +#else + const char *zSchema; + Tcl_Obj *pValue; + unsigned char *pBA; + unsigned char *pData; + int len, xrc; + + if( objc==3 ){ + zSchema = 0; + pValue = objv[2]; + }else if( objc==4 ){ + zSchema = Tcl_GetString(objv[2]); + pValue = objv[3]; + }else{ + Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE"); + rc = TCL_ERROR; + break; + } + pBA = Tcl_GetByteArrayFromObj(pValue, &len); + pData = sqlite3_malloc64( len ); + if( pData==0 && len>0 ){ + Tcl_AppendResult(interp, "out of memory", (char*)0); + rc = TCL_ERROR; + }else{ + if( len>0 ) memcpy(pData, pBA, len); + xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len, + SQLITE_DESERIALIZE_FREEONCLOSE | + SQLITE_DESERIALIZE_RESIZEABLE); + if( xrc ){ + Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0); + rc = TCL_ERROR; + } + } +#endif + break; + } + /* ** $db enable_load_extension BOOLEAN ** @@ -2885,6 +2939,39 @@ static int SQLITE_TCLAPI DbObjCmd( break; } + /* + ** $db serialize ?DATABASE? + ** + ** Return a serialization of a database. + */ + case DB_SERIALIZE: { +#ifndef SQLITE_ENABLE_DESERIALIZE + Tcl_AppendResult(interp, "MEMDB not available in this build", + (char*)0); + rc = TCL_ERROR; +#else + const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main"; + sqlite3_int64 sz = 0; + unsigned char *pData; + if( objc!=2 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?"); + rc = TCL_ERROR; + }else{ + int needFree; + pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY); + if( pData ){ + needFree = 0; + }else{ + pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0); + needFree = 1; + } + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz)); + if( needFree ) sqlite3_free(pData); + } +#endif + break; + } + /* ** $db status (step|sort|autoindex|vmstep) ** @@ -3286,7 +3373,42 @@ static int SQLITE_TCLAPI DbObjCmd( ** Return the version string for this database. */ case DB_VERSION: { - Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); + int i; + for(i=2; ibLegacyPrepare) ){ + return TCL_ERROR; + } + }else + + /* $db version -last-stmt-ptr + ** + ** Return a string which is a hex encoding of the pointer to the + ** most recent sqlite3_stmt in the statement cache. + */ + if( strcmp(zArg, "-last-stmt-ptr")==0 ){ + char zBuf[100]; + sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", + pDb->stmtList ? pDb->stmtList->pStmt: 0); + Tcl_SetResult(interp, zBuf, TCL_VOLATILE); + }else +#endif /* SQLITE_TEST */ + { + Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0); + return TCL_ERROR; + } + } + if( i==2 ){ + Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); + } break; } @@ -3310,6 +3432,25 @@ static int SQLITE_TCLAPI DbObjCmdAdaptor( } #endif /* SQLITE_TCL_NRE */ +/* +** Issue the usage message when the "sqlite3" command arguments are +** incorrect. +*/ +static int sqliteCmdUsage( + Tcl_Interp *interp, + Tcl_Obj *const*objv +){ + Tcl_WrongNumArgs(interp, 1, objv, + "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" + " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" + " ?-reuse-schema BOOLEAN?" +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) + " ?-key CODECKEY?" +#endif + ); + return TCL_ERROR; +} + /* ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? ** ?-create BOOLEAN? ?-nomutex BOOLEAN? @@ -3335,7 +3476,7 @@ static int SQLITE_TCLAPI DbMain( const char *zArg; char *zErrMsg; int i; - const char *zFile; + const char *zFile = 0; const char *zVfs = 0; int flags; Tcl_DString translatedFilename; @@ -3346,7 +3487,7 @@ static int SQLITE_TCLAPI DbMain( int rc; /* In normal use, each TCL interpreter runs in a single thread. So - ** by default, we can turn of mutexing on SQLite database connections. + ** by default, we can turn off mutexing on SQLite database connections. ** However, for testing purposes it is useful to have mutexes turned ** on. So, by default, mutexes default off. But if compiled with ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. @@ -3357,6 +3498,7 @@ static int SQLITE_TCLAPI DbMain( flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; #endif + if( objc==1 ) return sqliteCmdUsage(interp, objv); if( objc==2 ){ zArg = Tcl_GetStringFromObj(objv[1], 0); if( strcmp(zArg,"-version")==0 ){ @@ -3375,18 +3517,26 @@ static int SQLITE_TCLAPI DbMain( #endif return TCL_OK; } + if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv); } - for(i=3; i+1db, flags, zVfs); Tcl_DStringFree(&translatedFilename); @@ -3555,741 +3694,73 @@ int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } #endif -#ifdef TCLSH -/***************************************************************************** -** All of the code that follows is used to build standalone TCL interpreters -** that are statically linked with SQLite. Enable these by compiling -** with -DTCLSH=n where n can be 1 or 2. An n of 1 generates a standard -** tclsh but with SQLite built in. An n of 2 generates the SQLite space -** analysis program. +/* +** If the TCLSH macro is defined, add code to make a stand-alone program. */ +#if defined(TCLSH) -#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -/* - * If compiled on a machine that doesn't have a 32-bit integer, - * you just set "uint32" to the appropriate datatype for an - * unsigned 32-bit integer. For example: - * - * cc -Duint32='unsigned long' md5.c - * - */ -#ifndef uint32 -# define uint32 unsigned int -#endif - -struct MD5Context { - int isInit; - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; -typedef struct MD5Context MD5Context; - -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse (unsigned char *buf, unsigned longs){ - uint32 t; - do { - t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 | - ((unsigned)buf[1]<<8 | buf[0]); - *(uint32 *)buf = t; - buf += 4; - } while (--longs); -} -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -static void MD5Transform(uint32 buf[4], const uint32 in[16]){ - register uint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -static void MD5Init(MD5Context *ctx){ - ctx->isInit = 1; - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -static -void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){ - uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32)len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if ( t ) { - unsigned char *p = (unsigned char *)ctx->in + t; - - t = 64-t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (uint32 *)ctx->in); - buf += t; - len -= t; - } - - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (uint32 *)ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -static void MD5Final(unsigned char digest[16], MD5Context *ctx){ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (uint32 *)ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count-8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - memcpy(ctx->in + 14*4, ctx->bits, 8); - - MD5Transform(ctx->buf, (uint32 *)ctx->in); - byteReverse((unsigned char *)ctx->buf, 4); - memcpy(digest, ctx->buf, 16); -} - -/* -** Convert a 128-bit MD5 digest into a 32-digit base-16 number. +/* This is the main routine for an ordinary TCL shell. If there are +** are arguments, run the first argument as a script. Otherwise, +** read TCL commands from standard input */ -static void MD5DigestToBase16(unsigned char *digest, char *zBuf){ - static char const zEncode[] = "0123456789abcdef"; - int i, j; - - for(j=i=0; i<16; i++){ - int a = digest[i]; - zBuf[j++] = zEncode[(a>>4)&0xf]; - zBuf[j++] = zEncode[a & 0xf]; - } - zBuf[j] = 0; -} - - -/* -** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers -** each representing 16 bits of the digest and separated from each -** other by a "-" character. -*/ -static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){ - int i, j; - unsigned int x; - for(i=j=0; i<16; i+=2){ - x = digest[i]*256 + digest[i+1]; - if( i>0 ) zDigest[j++] = '-'; - sqlite3_snprintf(50-j, &zDigest[j], "%05u", x); - j += 5; - } - zDigest[j] = 0; -} - -/* -** A TCL command for md5. The argument is the text to be hashed. The -** Result is the hash in base64. -*/ -static int SQLITE_TCLAPI md5_cmd( - void*cd, - Tcl_Interp *interp, - int argc, - const char **argv -){ - MD5Context ctx; - unsigned char digest[16]; - char zBuf[50]; - void (*converter)(unsigned char*, char*); - - if( argc!=2 ){ - Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], - " TEXT\"", (char*)0); - return TCL_ERROR; - } - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1])); - MD5Final(digest, &ctx); - converter = (void(*)(unsigned char*,char*))cd; - converter(digest, zBuf); - Tcl_AppendResult(interp, zBuf, (char*)0); - return TCL_OK; -} - -/* -** A TCL command to take the md5 hash of a file. The argument is the -** name of the file. -*/ -static int SQLITE_TCLAPI md5file_cmd( - void*cd, - Tcl_Interp *interp, - int argc, - const char **argv -){ - FILE *in; - int ofst; - int amt; - MD5Context ctx; - void (*converter)(unsigned char*, char*); - unsigned char digest[16]; - char zBuf[10240]; - - if( argc!=2 && argc!=4 ){ - Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], - " FILENAME [OFFSET AMT]\"", (char*)0); - return TCL_ERROR; - } - if( argc==4 ){ - ofst = atoi(argv[2]); - amt = atoi(argv[3]); - }else{ - ofst = 0; - amt = 2147483647; - } - in = fopen(argv[1],"rb"); - if( in==0 ){ - Tcl_AppendResult(interp,"unable to open file \"", argv[1], - "\" for reading", (char*)0); - return TCL_ERROR; - } - fseek(in, ofst, SEEK_SET); - MD5Init(&ctx); - while( amt>0 ){ - int n; - n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in); - if( n<=0 ) break; - MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n); - amt -= n; - } - fclose(in); - MD5Final(digest, &ctx); - converter = (void(*)(unsigned char*,char*))cd; - converter(digest, zBuf); - Tcl_AppendResult(interp, zBuf, (char*)0); - return TCL_OK; -} - -/* -** Register the four new TCL commands for generating MD5 checksums -** with the TCL interpreter. -*/ -int Md5_Init(Tcl_Interp *interp){ - Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, - MD5DigestToBase16, 0); - Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd, - MD5DigestToBase10x8, 0); - Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, - MD5DigestToBase16, 0); - Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd, - MD5DigestToBase10x8, 0); - return TCL_OK; -} -#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */ - -#if defined(SQLITE_TEST) -/* -** During testing, the special md5sum() aggregate function is available. -** inside SQLite. The following routines implement that function. -*/ -static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){ - MD5Context *p; - int i; - if( argc<1 ) return; - p = sqlite3_aggregate_context(context, sizeof(*p)); - if( p==0 ) return; - if( !p->isInit ){ - MD5Init(p); - } - for(i=0; i \"\n" - "} else {\n" - "puts -nonewline \"% \"\n" - "}\n" - "flush stdout\n" - "append line [gets stdin]\n" - "if {[info complete $line]} {\n" - "if {[catch {uplevel #0 $line} result]} {\n" - "puts stderr \"Error: $result\"\n" - "} elseif {$result!=\"\"} {\n" - "puts $result\n" + "if {[llength $argv]>=1} {\n" + "set argv0 [lindex $argv 0]\n" + "set argv [lrange $argv 1 end]\n" + "source $argv0\n" + "} else {\n" + "set line {}\n" + "while {![eof stdin]} {\n" + "if {$line!=\"\"} {\n" + "puts -nonewline \"> \"\n" + "} else {\n" + "puts -nonewline \"% \"\n" + "}\n" + "flush stdout\n" + "append line [gets stdin]\n" + "if {[info complete $line]} {\n" + "if {[catch {uplevel #0 $line} result]} {\n" + "puts stderr \"Error: $result\"\n" + "} elseif {$result!=\"\"} {\n" + "puts $result\n" + "}\n" + "set line {}\n" + "} else {\n" + "append line \\n\n" "}\n" - "set line {}\n" - "} else {\n" - "append line \\n\n" "}\n" "}\n" ; return zMainloop; } -#endif -#if TCLSH==2 -static const char *tclsh_main_loop(void); -#endif - -#ifdef SQLITE_TEST -static void init_all(Tcl_Interp *); -static int SQLITE_TCLAPI init_all_cmd( - ClientData cd, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - - Tcl_Interp *slave; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "SLAVE"); - return TCL_ERROR; - } - - slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1])); - if( !slave ){ - return TCL_ERROR; - } - - init_all(slave); - return TCL_OK; -} - -/* -** Tclcmd: db_use_legacy_prepare DB BOOLEAN -** -** The first argument to this command must be a database command created by -** [sqlite3]. If the second argument is true, then the handle is configured -** to use the sqlite3_prepare_v2() function to prepare statements. If it -** is false, sqlite3_prepare(). -*/ -static int SQLITE_TCLAPI db_use_legacy_prepare_cmd( - ClientData cd, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - Tcl_CmdInfo cmdInfo; - SqliteDb *pDb; - int bPrepare; - - if( objc!=3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN"); - return TCL_ERROR; - } - - if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ - Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0); - return TCL_ERROR; - } - pDb = (SqliteDb*)cmdInfo.objClientData; - if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){ - return TCL_ERROR; - } - - pDb->bLegacyPrepare = bPrepare; - - Tcl_ResetResult(interp); - return TCL_OK; -} - -/* -** Tclcmd: db_last_stmt_ptr DB -** -** If the statement cache associated with database DB is not empty, -** return the text representation of the most recently used statement -** handle. -*/ -static int SQLITE_TCLAPI db_last_stmt_ptr( - ClientData cd, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*); - Tcl_CmdInfo cmdInfo; - SqliteDb *pDb; - sqlite3_stmt *pStmt = 0; - char zBuf[100]; - - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB"); - return TCL_ERROR; - } - - if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ - Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0); - return TCL_ERROR; - } - pDb = (SqliteDb*)cmdInfo.objClientData; - - if( pDb->stmtList ) pStmt = pDb->stmtList->pStmt; - if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ){ - return TCL_ERROR; - } - Tcl_SetResult(interp, zBuf, TCL_VOLATILE); - - return TCL_OK; -} -#endif /* SQLITE_TEST */ - -/* -** Configure the interpreter passed as the first argument to have access -** to the commands and linked variables that make up: -** -** * the [sqlite3] extension itself, -** -** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and -** -** * If SQLITE_TEST is set, the various test interfaces used by the Tcl -** test suite. -*/ -static void init_all(Tcl_Interp *interp){ - Sqlite3_Init(interp); - -#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) - Md5_Init(interp); -#endif - -#ifdef SQLITE_TEST - { - extern int Sqliteconfig_Init(Tcl_Interp*); - extern int Sqlitetest1_Init(Tcl_Interp*); - extern int Sqlitetest2_Init(Tcl_Interp*); - extern int Sqlitetest3_Init(Tcl_Interp*); - extern int Sqlitetest4_Init(Tcl_Interp*); - extern int Sqlitetest5_Init(Tcl_Interp*); - extern int Sqlitetest6_Init(Tcl_Interp*); - extern int Sqlitetest7_Init(Tcl_Interp*); - extern int Sqlitetest8_Init(Tcl_Interp*); - extern int Sqlitetest9_Init(Tcl_Interp*); - extern int Sqlitetestasync_Init(Tcl_Interp*); - extern int Sqlitetest_autoext_Init(Tcl_Interp*); - extern int Sqlitetest_blob_Init(Tcl_Interp*); - extern int Sqlitetest_demovfs_Init(Tcl_Interp *); - extern int Sqlitetest_func_Init(Tcl_Interp*); - extern int Sqlitetest_hexio_Init(Tcl_Interp*); - extern int Sqlitetest_init_Init(Tcl_Interp*); - extern int Sqlitetest_malloc_Init(Tcl_Interp*); - extern int Sqlitetest_mutex_Init(Tcl_Interp*); - extern int Sqlitetestschema_Init(Tcl_Interp*); - extern int Sqlitetestsse_Init(Tcl_Interp*); - extern int Sqlitetesttclvar_Init(Tcl_Interp*); - extern int Sqlitetestfs_Init(Tcl_Interp*); - extern int SqlitetestThread_Init(Tcl_Interp*); - extern int SqlitetestOnefile_Init(); - extern int SqlitetestOsinst_Init(Tcl_Interp*); - extern int Sqlitetestbackup_Init(Tcl_Interp*); - extern int Sqlitetestintarray_Init(Tcl_Interp*); - extern int Sqlitetestvfs_Init(Tcl_Interp *); - extern int Sqlitetestrtree_Init(Tcl_Interp*); - extern int Sqlitequota_Init(Tcl_Interp*); - extern int Sqlitemultiplex_Init(Tcl_Interp*); - extern int SqliteSuperlock_Init(Tcl_Interp*); - extern int SqlitetestSyscall_Init(Tcl_Interp*); -#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) - extern int TestSession_Init(Tcl_Interp*); -#endif - extern int Fts5tcl_Init(Tcl_Interp *); - extern int SqliteRbu_Init(Tcl_Interp*); - extern int Sqlitetesttcl_Init(Tcl_Interp*); -#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) - extern int Sqlitetestfts3_Init(Tcl_Interp *interp); -#endif - -#ifdef SQLITE_ENABLE_ZIPVFS - extern int Zipvfs_Init(Tcl_Interp*); - Zipvfs_Init(interp); -#endif - - Sqliteconfig_Init(interp); - Sqlitetest1_Init(interp); - Sqlitetest2_Init(interp); - Sqlitetest3_Init(interp); - Sqlitetest4_Init(interp); - Sqlitetest5_Init(interp); - Sqlitetest6_Init(interp); - Sqlitetest7_Init(interp); - Sqlitetest8_Init(interp); - Sqlitetest9_Init(interp); - Sqlitetestasync_Init(interp); - Sqlitetest_autoext_Init(interp); - Sqlitetest_blob_Init(interp); - Sqlitetest_demovfs_Init(interp); - Sqlitetest_func_Init(interp); - Sqlitetest_hexio_Init(interp); - Sqlitetest_init_Init(interp); - Sqlitetest_malloc_Init(interp); - Sqlitetest_mutex_Init(interp); - Sqlitetestschema_Init(interp); - Sqlitetesttclvar_Init(interp); - Sqlitetestfs_Init(interp); - SqlitetestThread_Init(interp); - SqlitetestOnefile_Init(); - SqlitetestOsinst_Init(interp); - Sqlitetestbackup_Init(interp); - Sqlitetestintarray_Init(interp); - Sqlitetestvfs_Init(interp); - Sqlitetestrtree_Init(interp); - Sqlitequota_Init(interp); - Sqlitemultiplex_Init(interp); - SqliteSuperlock_Init(interp); - SqlitetestSyscall_Init(interp); -#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) - TestSession_Init(interp); -#endif - Fts5tcl_Init(interp); - SqliteRbu_Init(interp); - Sqlitetesttcl_Init(interp); - -#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) - Sqlitetestfts3_Init(interp); -#endif - - Tcl_CreateObjCommand( - interp, "load_testfixture_extensions", init_all_cmd, 0, 0 - ); - Tcl_CreateObjCommand( - interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0 - ); - Tcl_CreateObjCommand( - interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0 - ); - -#ifdef SQLITE_SSE - Sqlitetestsse_Init(interp); -#endif - } -#endif -} - -/* Needed for the setrlimit() system call on unix */ -#if defined(unix) -#include -#endif #define TCLSH_MAIN main /* Needed to fake out mktclapp */ int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){ Tcl_Interp *interp; - -#if !defined(_WIN32_WCE) - if( getenv("BREAK") ){ - fprintf(stderr, - "attach debugger to process %d and press any key to continue.\n", - GETPID()); - fgetc(stdin); - } + int i; + const char *zScript = 0; + char zArgc[32]; +#if defined(TCLSH_INIT_PROC) + extern const char *TCLSH_INIT_PROC(Tcl_Interp*); #endif - /* Since the primary use case for this binary is testing of SQLite, - ** be sure to generate core files if we crash */ -#if defined(SQLITE_TEST) && defined(unix) - { struct rlimit x; - getrlimit(RLIMIT_CORE, &x); - x.rlim_cur = x.rlim_max; - setrlimit(RLIMIT_CORE, &x); +#if !defined(_WIN32_WCE) + if( getenv("SQLITE_DEBUG_BREAK") ){ + if( isatty(0) && isatty(2) ){ + fprintf(stderr, + "attach debugger to process %d and press any key to continue.\n", + GETPID()); + fgetc(stdin); + }else{ +#if defined(_WIN32) || defined(WIN32) + DebugBreak(); +#elif defined(SIGTRAP) + raise(SIGTRAP); +#endif + } } -#endif /* SQLITE_TEST && unix */ - +#endif /* Call sqlite3_shutdown() once before doing anything else. This is to ** test that sqlite3_shutdown() can be safely called by a process before @@ -4299,32 +3770,27 @@ int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){ Tcl_FindExecutable(argv[0]); Tcl_SetSystemEncoding(NULL, "utf-8"); interp = Tcl_CreateInterp(); + Sqlite3_Init(interp); -#if TCLSH==2 - sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); -#endif - - init_all(interp); - if( argc>=2 ){ - int i; - char zArgc[32]; - sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH)); - Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); - Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); - for(i=3-TCLSH; iargvIndex = ++nArg; + pUsage->omit = 1; } - string_concat(&zQuery, zNew, 1, &rc); - - zSep = "AND"; - pUsage->argvIndex = ++nArg; - pUsage->omit = 1; } } diff --git a/src/test_bestindex.c b/src/test_bestindex.c index 94017f0349..2cd79baf2b 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -414,6 +414,16 @@ static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ zOp = "glob"; break; case SQLITE_INDEX_CONSTRAINT_REGEXP: zOp = "regexp"; break; + case SQLITE_INDEX_CONSTRAINT_NE: + zOp = "ne"; break; + case SQLITE_INDEX_CONSTRAINT_ISNOT: + zOp = "isnot"; break; + case SQLITE_INDEX_CONSTRAINT_ISNOTNULL: + zOp = "isnotnull"; break; + case SQLITE_INDEX_CONSTRAINT_ISNULL: + zOp = "isnull"; break; + case SQLITE_INDEX_CONSTRAINT_IS: + zOp = "is"; break; } Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("op", -1)); diff --git a/src/test_config.c b/src/test_config.c index 9ff84dcec0..f017abc307 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -124,7 +124,7 @@ static void set_options(Tcl_Interp *interp){ STRINGVALUE(SQLITE_MAX_WORKER_THREADS), TCL_GLOBAL_ONLY ); -#if 1 /* def SQLITE_MEMDEBUG */ +#ifdef SQLITE_MEMDEBUG Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY); @@ -148,6 +148,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "hiddencolumns", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_DESERIALIZE + Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_MEMSYS3 Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY); #else @@ -160,6 +166,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "mem5", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + Tcl_SetVar2(interp, "sqlite_options", "offset_sql_func","1",TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "offset_sql_func","0",TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_PREUPDATE_HOOK Tcl_SetVar2(interp, "sqlite_options", "preupdate", "1", TCL_GLOBAL_ONLY); #else @@ -214,6 +226,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_HAS_CODEC + Tcl_SetVar2(interp, "sqlite_options", "has_codec", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "has_codec", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "0", TCL_GLOBAL_ONLY); #else @@ -423,6 +441,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "icu", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_ICU_COLLATIONS + Tcl_SetVar2(interp, "sqlite_options", "icu_collations", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "icu_collations", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_INCRBLOB Tcl_SetVar2(interp, "sqlite_options", "incrblob", "0", TCL_GLOBAL_ONLY); #else @@ -483,6 +507,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double", Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); +#ifdef SQLITE_ENABLE_NULL_TRIM + Tcl_SetVar2(interp, "sqlite_options", "null_trim", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "null_trim", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_OR_OPTIMIZATION Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY); #else @@ -690,6 +720,12 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "unlock_notify", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_FAST_SECURE_DELETE + Tcl_SetVar2(interp, "sqlite_options", "fast_secure_delete", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "fast_secure_delete", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_SECURE_DELETE Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "1", TCL_GLOBAL_ONLY); #else @@ -726,6 +762,12 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_WINDOWFUNC + Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "1", TCL_GLOBAL_ONLY); +#endif + #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ diff --git a/src/test_func.c b/src/test_func.c index c7860fe887..2a7103f88e 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -791,6 +791,123 @@ abuse_err: } +/* +** SQLite user defined function to use with matchinfo() to calculate the +** relevancy of an FTS match. The value returned is the relevancy score +** (a real value greater than or equal to zero). A larger value indicates +** a more relevant document. +** +** The overall relevancy returned is the sum of the relevancies of each +** column value in the FTS table. The relevancy of a column value is the +** sum of the following for each reportable phrase in the FTS query: +** +** ( / ) * +** +** where is the number of instances of the phrase in the +** column value of the current row and is the number +** of instances of the phrase in the same column of all rows in the FTS +** table. The is a weighting factor assigned to each +** column by the caller (see below). +** +** The first argument to this function must be the return value of the FTS +** matchinfo() function. Following this must be one argument for each column +** of the FTS table containing a numeric weight factor for the corresponding +** column. Example: +** +** CREATE VIRTUAL TABLE documents USING fts3(title, content) +** +** The following query returns the docids of documents that match the full-text +** query sorted from most to least relevant. When calculating +** relevance, query term instances in the 'title' column are given twice the +** weighting of those in the 'content' column. +** +** SELECT docid FROM documents +** WHERE documents MATCH +** ORDER BY rank(matchinfo(documents), 1.0, 0.5) DESC +*/ +static void rankfunc(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ + int *aMatchinfo; /* Return value of matchinfo() */ + int nMatchinfo; /* Number of elements in aMatchinfo[] */ + int nCol = 0; /* Number of columns in the table */ + int nPhrase = 0; /* Number of phrases in the query */ + int iPhrase; /* Current phrase */ + double score = 0.0; /* Value to return */ + + assert( sizeof(int)==4 ); + + /* Check that the number of arguments passed to this function is correct. + ** If not, jump to wrong_number_args. Set aMatchinfo to point to the array + ** of unsigned integer values returned by FTS function matchinfo. Set + ** nPhrase to contain the number of reportable phrases in the users full-text + ** query, and nCol to the number of columns in the table. Then check that the + ** size of the matchinfo blob is as expected. Return an error if it is not. + */ + if( nVal<1 ) goto wrong_number_args; + aMatchinfo = (int*)sqlite3_value_blob(apVal[0]); + nMatchinfo = sqlite3_value_bytes(apVal[0]) / sizeof(int); + if( nMatchinfo>=2 ){ + nPhrase = aMatchinfo[0]; + nCol = aMatchinfo[1]; + } + if( nMatchinfo!=(2+3*nCol*nPhrase) ){ + sqlite3_result_error(pCtx, + "invalid matchinfo blob passed to function rank()", -1); + return; + } + if( nVal!=(1+nCol) ) goto wrong_number_args; + + /* Iterate through each phrase in the users query. */ + for(iPhrase=0; iPhrase / ) * + ** + ** aPhraseinfo[] points to the start of the data for phrase iPhrase. So + ** the hit count and global hit counts for each column are found in + ** aPhraseinfo[iCol*3] and aPhraseinfo[iCol*3+1], respectively. + */ + int *aPhraseinfo = &aMatchinfo[2 + iPhrase*nCol*3]; + for(iCol=0; iCol0 ){ + score += ((double)nHitCount / (double)nGlobalHitCount) * weight; + } + } + } + + sqlite3_result_double(pCtx, score); + return; + + /* Jump here if the wrong number of arguments are passed to this function */ +wrong_number_args: + sqlite3_result_error(pCtx, "wrong number of arguments to function rank()", -1); +} + +static int SQLITE_TCLAPI install_fts3_rank_function( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); + sqlite3 *db; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + sqlite3_create_function(db, "rank", -1, SQLITE_UTF8, 0, rankfunc, 0, 0); + return TCL_OK; +} + + /* ** Register commands with the TCL interpreter. */ @@ -801,6 +918,7 @@ int Sqlitetest_func_Init(Tcl_Interp *interp){ } aObjCmd[] = { { "autoinstall_test_functions", autoinstall_test_funcs }, { "abuse_create_function", abuse_create_function }, + { "install_fts3_rank_function", install_fts3_rank_function }, }; int i; extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *); diff --git a/src/test_malloc.c b/src/test_malloc.c index e8c248f958..32a03e7191 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -32,6 +32,8 @@ static struct MemFault { int nRepeat; /* Number of times to repeat the failure */ int nBenign; /* Number of benign failures seen since last config */ int nFail; /* Number of failures seen since last config */ + int nOkBefore; /* Successful allocations prior to the first fault */ + int nOkAfter; /* Successful allocations after a fault */ u8 enable; /* True if enabled */ int isInstalled; /* True if the fault simulation layer is installed */ int isBenignMode; /* True if malloc failures are considered benign */ @@ -47,18 +49,32 @@ static void sqlite3Fault(void){ cnt++; } +/* +** This routine exists as a place to set a breakpoint that will +** fire the first time any malloc() fails on a single test case. +** The sqlite3Fault() routine above runs on every malloc() failure. +** This routine only runs on the first such failure. +*/ +static void sqlite3FirstFault(void){ + static int cnt2 = 0; + cnt2++; +} + /* ** Check to see if a fault should be simulated. Return true to simulate ** the fault. Return false if the fault should not be simulated. */ static int faultsimStep(void){ if( likely(!memfault.enable) ){ + memfault.nOkAfter++; return 0; } if( memfault.iCountdown>0 ){ memfault.iCountdown--; + memfault.nOkBefore++; return 0; } + if( memfault.nFail==0 ) sqlite3FirstFault(); sqlite3Fault(); memfault.nFail++; if( memfault.isBenignMode>0 ){ @@ -133,6 +149,8 @@ static void faultsimConfig(int nDelay, int nRepeat){ memfault.nRepeat = nRepeat; memfault.nBenign = 0; memfault.nFail = 0; + memfault.nOkBefore = 0; + memfault.nOkAfter = 0; memfault.enable = nDelay>=0; /* Sometimes, when running multi-threaded tests, the isBenignMode @@ -887,46 +905,6 @@ static int SQLITE_TCLAPI test_memdebug_log( return TCL_OK; } -/* -** Usage: sqlite3_config_scratch SIZE N -** -** Set the scratch memory buffer using SQLITE_CONFIG_SCRATCH. -** The buffer is static and is of limited size. N might be -** adjusted downward as needed to accommodate the requested size. -** The revised value of N is returned. -** -** A negative SIZE causes the buffer pointer to be NULL. -*/ -static int SQLITE_TCLAPI test_config_scratch( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - int sz, N, rc; - Tcl_Obj *pResult; - static char *buf = 0; - if( objc!=3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "SIZE N"); - return TCL_ERROR; - } - if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR; - if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR; - free(buf); - if( sz<0 ){ - buf = 0; - rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, (void*)0, 0, 0); - }else{ - buf = malloc( sz*N + 1 ); - rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N); - } - pResult = Tcl_NewObj(); - Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); - Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N)); - Tcl_SetObjResult(interp, pResult); - return TCL_OK; -} - /* ** Usage: sqlite3_config_pagecache SIZE N ** @@ -1423,6 +1401,7 @@ static int SQLITE_TCLAPI test_db_status( { "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE }, { "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS }, { "CACHE_USED_SHARED", SQLITE_DBSTATUS_CACHE_USED_SHARED }, + { "CACHE_SPILL", SQLITE_DBSTATUS_CACHE_SPILL }, }; Tcl_Obj *pResult; if( objc!=4 ){ @@ -1538,7 +1517,6 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ { "sqlite3_memdebug_settitle", test_memdebug_settitle ,0 }, { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count ,0 }, { "sqlite3_memdebug_log", test_memdebug_log ,0 }, - { "sqlite3_config_scratch", test_config_scratch ,0 }, { "sqlite3_config_pagecache", test_config_pagecache ,0 }, { "sqlite3_config_alt_pcache", test_alt_pcache ,0 }, { "sqlite3_status", test_status ,0 }, diff --git a/src/test_md5.c b/src/test_md5.c new file mode 100644 index 0000000000..b670026861 --- /dev/null +++ b/src/test_md5.c @@ -0,0 +1,450 @@ +/* +** 2017-10-13 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code to implement an MD5 extension to TCL. +*/ +#include "sqlite3.h" +#include +#include +#include "sqlite3.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif +#endif + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +/* + * If compiled on a machine that doesn't have a 32-bit integer, + * you just set "uint32" to the appropriate datatype for an + * unsigned 32-bit integer. For example: + * + * cc -Duint32='unsigned long' md5.c + * + */ +#ifndef uint32 +# define uint32 unsigned int +#endif + +struct MD5Context { + int isInit; + uint32 buf[4]; + uint32 bits[2]; + unsigned char in[64]; +}; +typedef struct MD5Context MD5Context; + +/* + * Note: this code is harmless on little-endian machines. + */ +static void byteReverse (unsigned char *buf, unsigned longs){ + uint32 t; + do { + t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 | + ((unsigned)buf[1]<<8 | buf[0]); + *(uint32 *)buf = t; + buf += 4; + } while (--longs); +} +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void MD5Transform(uint32 buf[4], const uint32 in[16]){ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +static void MD5Init(MD5Context *ctx){ + ctx->isInit = 1; + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +static +void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){ + uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32)len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if ( t ) { + unsigned char *p = (unsigned char *)ctx->in + t; + + t = 64-t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *)ctx->in); + buf += t; + len -= t; + } + + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *)ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +static void MD5Final(unsigned char digest[16], MD5Context *ctx){ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *)ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count-8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + memcpy(ctx->in + 14*4, ctx->bits, 8); + + MD5Transform(ctx->buf, (uint32 *)ctx->in); + byteReverse((unsigned char *)ctx->buf, 4); + memcpy(digest, ctx->buf, 16); +} + +/* +** Convert a 128-bit MD5 digest into a 32-digit base-16 number. +*/ +static void MD5DigestToBase16(unsigned char *digest, char *zBuf){ + static char const zEncode[] = "0123456789abcdef"; + int i, j; + + for(j=i=0; i<16; i++){ + int a = digest[i]; + zBuf[j++] = zEncode[(a>>4)&0xf]; + zBuf[j++] = zEncode[a & 0xf]; + } + zBuf[j] = 0; +} + + +/* +** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers +** each representing 16 bits of the digest and separated from each +** other by a "-" character. +*/ +static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){ + int i, j; + unsigned int x; + for(i=j=0; i<16; i+=2){ + x = digest[i]*256 + digest[i+1]; + if( i>0 ) zDigest[j++] = '-'; + sqlite3_snprintf(50-j, &zDigest[j], "%05u", x); + j += 5; + } + zDigest[j] = 0; +} + +/* +** A TCL command for md5. The argument is the text to be hashed. The +** Result is the hash in base64. +*/ +static int SQLITE_TCLAPI md5_cmd( + void*cd, + Tcl_Interp *interp, + int argc, + const char **argv +){ + MD5Context ctx; + unsigned char digest[16]; + char zBuf[50]; + void (*converter)(unsigned char*, char*); + + if( argc!=2 ){ + Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], + " TEXT\"", (char*)0); + return TCL_ERROR; + } + MD5Init(&ctx); + MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1])); + MD5Final(digest, &ctx); + converter = (void(*)(unsigned char*,char*))cd; + converter(digest, zBuf); + Tcl_AppendResult(interp, zBuf, (char*)0); + return TCL_OK; +} + +/* +** A TCL command to take the md5 hash of a file. The argument is the +** name of the file. +*/ +static int SQLITE_TCLAPI md5file_cmd( + void*cd, + Tcl_Interp *interp, + int argc, + const char **argv +){ + FILE *in; + int ofst; + int amt; + MD5Context ctx; + void (*converter)(unsigned char*, char*); + unsigned char digest[16]; + char zBuf[10240]; + + if( argc!=2 && argc!=4 ){ + Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], + " FILENAME [OFFSET AMT]\"", (char*)0); + return TCL_ERROR; + } + if( argc==4 ){ + ofst = atoi(argv[2]); + amt = atoi(argv[3]); + }else{ + ofst = 0; + amt = 2147483647; + } + in = fopen(argv[1],"rb"); + if( in==0 ){ + Tcl_AppendResult(interp,"unable to open file \"", argv[1], + "\" for reading", (char*)0); + return TCL_ERROR; + } + fseek(in, ofst, SEEK_SET); + MD5Init(&ctx); + while( amt>0 ){ + int n; + n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in); + if( n<=0 ) break; + MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n); + amt -= n; + } + fclose(in); + MD5Final(digest, &ctx); + converter = (void(*)(unsigned char*,char*))cd; + converter(digest, zBuf); + Tcl_AppendResult(interp, zBuf, (char*)0); + return TCL_OK; +} + +/* +** Register the four new TCL commands for generating MD5 checksums +** with the TCL interpreter. +*/ +int Md5_Init(Tcl_Interp *interp){ + Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, + MD5DigestToBase16, 0); + Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd, + MD5DigestToBase10x8, 0); + Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, + MD5DigestToBase16, 0); + Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd, + MD5DigestToBase10x8, 0); + return TCL_OK; +} + +/* +** During testing, the special md5sum() aggregate function is available. +** inside SQLite. The following routines implement that function. +*/ +static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){ + MD5Context *p; + int i; + if( argc<1 ) return; + p = sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( !p->isInit ){ + MD5Init(p); + } + for(i=0; i +#endif + +/* Forward declaration */ +static int SQLITE_TCLAPI load_testfixture_extensions( + ClientData cd, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +); + +/* +** This routine is the primary export of this file. +** +** Configure the interpreter passed as the first argument to have access +** to the commands and linked variables that make up: +** +** * the [sqlite3] extension itself, +** +** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and +** +** * If SQLITE_TEST is set, the various test interfaces used by the Tcl +** test suite. +*/ +const char *sqlite3TestInit(Tcl_Interp *interp){ + extern int Sqlite3_Init(Tcl_Interp*); + extern int Sqliteconfig_Init(Tcl_Interp*); + extern int Sqlitetest1_Init(Tcl_Interp*); + extern int Sqlitetest2_Init(Tcl_Interp*); + extern int Sqlitetest3_Init(Tcl_Interp*); + extern int Sqlitetest4_Init(Tcl_Interp*); + extern int Sqlitetest5_Init(Tcl_Interp*); + extern int Sqlitetest6_Init(Tcl_Interp*); + extern int Sqlitetest7_Init(Tcl_Interp*); + extern int Sqlitetest8_Init(Tcl_Interp*); + extern int Sqlitetest9_Init(Tcl_Interp*); + extern int Sqlitetestasync_Init(Tcl_Interp*); + extern int Sqlitetest_autoext_Init(Tcl_Interp*); + extern int Sqlitetest_blob_Init(Tcl_Interp*); + extern int Sqlitetest_demovfs_Init(Tcl_Interp *); + extern int Sqlitetest_func_Init(Tcl_Interp*); + extern int Sqlitetest_hexio_Init(Tcl_Interp*); + extern int Sqlitetest_init_Init(Tcl_Interp*); + extern int Sqlitetest_malloc_Init(Tcl_Interp*); + extern int Sqlitetest_mutex_Init(Tcl_Interp*); + extern int Sqlitetestschema_Init(Tcl_Interp*); + extern int Sqlitetestsse_Init(Tcl_Interp*); + extern int Sqlitetesttclvar_Init(Tcl_Interp*); + extern int Sqlitetestfs_Init(Tcl_Interp*); + extern int SqlitetestThread_Init(Tcl_Interp*); + extern int SqlitetestOnefile_Init(); + extern int SqlitetestOsinst_Init(Tcl_Interp*); + extern int Sqlitetestbackup_Init(Tcl_Interp*); + extern int Sqlitetestintarray_Init(Tcl_Interp*); + extern int Sqlitetestvfs_Init(Tcl_Interp *); + extern int Sqlitetestrtree_Init(Tcl_Interp*); + extern int Sqlitequota_Init(Tcl_Interp*); + extern int Sqlitemultiplex_Init(Tcl_Interp*); + extern int SqliteSuperlock_Init(Tcl_Interp*); + extern int SqlitetestSyscall_Init(Tcl_Interp*); +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) + extern int TestSession_Init(Tcl_Interp*); +#endif + extern int Md5_Init(Tcl_Interp*); + extern int Fts5tcl_Init(Tcl_Interp *); + extern int SqliteRbu_Init(Tcl_Interp*); + extern int Sqlitetesttcl_Init(Tcl_Interp*); +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) + extern int Sqlitetestfts3_Init(Tcl_Interp *interp); +#endif +#ifdef SQLITE_ENABLE_ZIPVFS + extern int Zipvfs_Init(Tcl_Interp*); +#endif + extern int TestExpert_Init(Tcl_Interp*); + extern int Sqlitetest_window_Init(Tcl_Interp *); + + Tcl_CmdInfo cmdInfo; + + /* Since the primary use case for this binary is testing of SQLite, + ** be sure to generate core files if we crash */ +#if defined(unix) + { struct rlimit x; + getrlimit(RLIMIT_CORE, &x); + x.rlim_cur = x.rlim_max; + setrlimit(RLIMIT_CORE, &x); + } +#endif /* unix */ + + if( Tcl_GetCommandInfo(interp, "sqlite3", &cmdInfo)==0 ){ + Sqlite3_Init(interp); + } +#ifdef SQLITE_ENABLE_ZIPVFS + Zipvfs_Init(interp); +#endif + Md5_Init(interp); + Sqliteconfig_Init(interp); + Sqlitetest1_Init(interp); + Sqlitetest2_Init(interp); + Sqlitetest3_Init(interp); + Sqlitetest4_Init(interp); + Sqlitetest5_Init(interp); + Sqlitetest6_Init(interp); + Sqlitetest7_Init(interp); + Sqlitetest8_Init(interp); + Sqlitetest9_Init(interp); + Sqlitetestasync_Init(interp); + Sqlitetest_autoext_Init(interp); + Sqlitetest_blob_Init(interp); + Sqlitetest_demovfs_Init(interp); + Sqlitetest_func_Init(interp); + Sqlitetest_hexio_Init(interp); + Sqlitetest_init_Init(interp); + Sqlitetest_malloc_Init(interp); + Sqlitetest_mutex_Init(interp); + Sqlitetestschema_Init(interp); + Sqlitetesttclvar_Init(interp); + Sqlitetestfs_Init(interp); + SqlitetestThread_Init(interp); + SqlitetestOnefile_Init(); + SqlitetestOsinst_Init(interp); + Sqlitetestbackup_Init(interp); + Sqlitetestintarray_Init(interp); + Sqlitetestvfs_Init(interp); + Sqlitetestrtree_Init(interp); + Sqlitequota_Init(interp); + Sqlitemultiplex_Init(interp); + SqliteSuperlock_Init(interp); + SqlitetestSyscall_Init(interp); +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) + TestSession_Init(interp); +#endif + Fts5tcl_Init(interp); + SqliteRbu_Init(interp); + Sqlitetesttcl_Init(interp); + +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) + Sqlitetestfts3_Init(interp); +#endif + TestExpert_Init(interp); + Sqlitetest_window_Init(interp); + + Tcl_CreateObjCommand( + interp, "load_testfixture_extensions", load_testfixture_extensions,0,0 + ); + return 0; +} + +/* tclcmd: load_testfixture_extensions +*/ +static int SQLITE_TCLAPI load_testfixture_extensions( + ClientData cd, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + + Tcl_Interp *slave; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SLAVE"); + return TCL_ERROR; + } + + slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1])); + if( !slave ){ + return TCL_ERROR; + } + + (void)sqlite3TestInit(slave); + return TCL_OK; +} diff --git a/src/test_tclvar.c b/src/test_tclvar.c index 8f7352112d..bf99a8eadb 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -15,6 +15,25 @@ ** ** The emphasis of this file is a virtual table that provides ** access to TCL variables. +** +** The TCLVAR eponymous virtual table has a schema like this: +** +** CREATE TABLE tclvar( +** name TEXT, -- base name of the variable: "x" in "$x(y)" +** arrayname TEXT, -- array index name: "y" in "$x(y)" +** value TEXT, -- the value of the variable +** fullname TEXT, -- the full name of the variable +** PRIMARY KEY(fullname) +** ) WITHOUT ROWID; +** +** DELETE, INSERT, and UPDATE operations use the "fullname" field to +** determine the variable to be modified. Changing "value" to NULL +** deletes the variable. +** +** For SELECT operations, the "name" and "arrayname" fields will always +** match the "fullname" field. For DELETE, INSERT, and UPDATE, the +** "name" and "arrayname" fields are ignored and the variable is modified +** according to "fullname" and "value" only. */ #include "sqliteInt.h" #if defined(INCLUDE_SQLITE_TCL_H) @@ -67,7 +86,12 @@ static int tclvarConnect( ){ tclvar_vtab *pVtab; static const char zSchema[] = - "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; + "CREATE TABLE x(" + " name TEXT," /* Base name */ + " arrayname TEXT," /* Array index */ + " value TEXT," /* Value */ + " fullname TEXT PRIMARY KEY" /* base(index) name */ + ") WITHOUT ROWID"; pVtab = sqlite3MallocZero( sizeof(*pVtab) ); if( pVtab==0 ) return SQLITE_NOMEM; *ppVtab = &pVtab->base; @@ -251,6 +275,16 @@ static int tclvarColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ sqlite3_result_text(ctx, Tcl_GetString(pVal), -1, SQLITE_TRANSIENT); break; } + case 3: { + char *z3; + if( p2 ){ + z3 = sqlite3_mprintf("%s(%s)", z1, z2); + sqlite3_result_text(ctx, z3, -1, sqlite3_free); + }else{ + sqlite3_result_text(ctx, z1, -1, SQLITE_TRANSIENT); + } + break; + } } return SQLITE_OK; } @@ -376,6 +410,58 @@ static int tclvarBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ return SQLITE_OK; } +/* +** Invoked for any UPDATE, INSERT, or DELETE against a tclvar table +*/ +static int tclvarUpdate( + sqlite3_vtab *tab, + int argc, + sqlite3_value **argv, + sqlite_int64 *pRowid +){ + tclvar_vtab *pTab = (tclvar_vtab*)tab; + if( argc==1 ){ + /* A DELETE operation. The variable to be deleted is stored in argv[0] */ + const char *zVar = (const char*)sqlite3_value_text(argv[0]); + Tcl_UnsetVar(pTab->interp, zVar, TCL_GLOBAL_ONLY); + return SQLITE_OK; + } + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + /* An INSERT operation */ + const char *zValue = (const char*)sqlite3_value_text(argv[4]); + const char *zName; + if( sqlite3_value_type(argv[5])!=SQLITE_TEXT ){ + tab->zErrMsg = sqlite3_mprintf("the 'fullname' column must be TEXT"); + return SQLITE_ERROR; + } + zName = (const char*)sqlite3_value_text(argv[5]); + if( zValue ){ + Tcl_SetVar(pTab->interp, zName, zValue, TCL_GLOBAL_ONLY); + }else{ + Tcl_UnsetVar(pTab->interp, zName, TCL_GLOBAL_ONLY); + } + return SQLITE_OK; + } + if( sqlite3_value_type(argv[0])==SQLITE_TEXT + && sqlite3_value_type(argv[1])==SQLITE_TEXT + ){ + /* An UPDATE operation */ + const char *zOldName = (const char*)sqlite3_value_text(argv[0]); + const char *zNewName = (const char*)sqlite3_value_text(argv[1]); + const char *zValue = (const char*)sqlite3_value_text(argv[4]); + + if( strcmp(zOldName, zNewName)!=0 || zValue==0 ){ + Tcl_UnsetVar(pTab->interp, zOldName, TCL_GLOBAL_ONLY); + } + if( zValue!=0 ){ + Tcl_SetVar(pTab->interp, zNewName, zValue, TCL_GLOBAL_ONLY); + } + return SQLITE_OK; + } + tab->zErrMsg = sqlite3_mprintf("prohibited TCL variable change"); + return SQLITE_ERROR; +} + /* ** A virtual table module that provides read-only access to a ** Tcl global variable namespace. @@ -394,7 +480,7 @@ static sqlite3_module tclvarModule = { tclvarEof, /* xEof - check for end of scan */ tclvarColumn, /* xColumn - read data */ tclvarRowid, /* xRowid - read data */ - 0, /* xUpdate */ + tclvarUpdate, /* xUpdate */ 0, /* xBegin */ 0, /* xSync */ 0, /* xCommit */ diff --git a/src/test_vfs.c b/src/test_vfs.c index fb987a6163..4a98ac214c 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -133,8 +133,9 @@ struct Testvfs { #define TESTVFS_UNLOCK_MASK 0x00020000 #define TESTVFS_LOCK_MASK 0x00040000 #define TESTVFS_CKLOCK_MASK 0x00080000 +#define TESTVFS_FCNTL_MASK 0x00100000 -#define TESTVFS_ALL_MASK 0x000FFFFF +#define TESTVFS_ALL_MASK 0x001FFFFF #define TESTVFS_MAX_PAGES 1024 @@ -517,7 +518,8 @@ static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){ ** File control method. For custom operations on an tvfs-file. */ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){ - TestvfsFd *p = tvfsGetFd(pFile); + TestvfsFd *pFd = tvfsGetFd(pFile); + Testvfs *p = (Testvfs *)pFd->pVfs->pAppData; if( op==SQLITE_FCNTL_PRAGMA ){ char **argv = (char**)pArg; if( sqlite3_stricmp(argv[1],"error")==0 ){ @@ -535,11 +537,34 @@ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){ return rc; } if( sqlite3_stricmp(argv[1], "filename")==0 ){ - argv[0] = sqlite3_mprintf("%s", p->zFilename); + argv[0] = sqlite3_mprintf("%s", pFd->zFilename); return SQLITE_OK; } } - return sqlite3OsFileControl(p->pReal, op, pArg); + if( p->pScript && (p->mask&TESTVFS_FCNTL_MASK) ){ + struct Fcntl { + int iFnctl; + const char *zFnctl; + } aF[] = { + { SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, "BEGIN_ATOMIC_WRITE" }, + { SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, "COMMIT_ATOMIC_WRITE" }, + }; + int i; + for(i=0; izFilename, -1), + Tcl_NewStringObj(aF[i].zFnctl, -1), + 0, 0 + ); + tvfsResultCode(p, &rc); + if( rc ) return rc; + } + } + return sqlite3OsFileControl(pFd->pReal, op, pArg); } /* @@ -1160,6 +1185,7 @@ static int SQLITE_TCLAPI testvfs_obj_cmd( { "xUnlock", TESTVFS_UNLOCK_MASK }, { "xLock", TESTVFS_LOCK_MASK }, { "xCheckReservedLock", TESTVFS_CKLOCK_MASK }, + { "xFileControl", TESTVFS_FCNTL_MASK }, }; Tcl_Obj **apElem = 0; int nElem = 0; diff --git a/src/test_windirent.c b/src/test_windirent.c index ca78d345d9..62165c4bea 100644 --- a/src/test_windirent.c +++ b/src/test_windirent.c @@ -14,7 +14,6 @@ */ #if defined(_WIN32) && defined(_MSC_VER) - #include "test_windirent.h" /* diff --git a/src/test_windirent.h b/src/test_windirent.h index 578e2a7c22..ada5322530 100644 --- a/src/test_windirent.h +++ b/src/test_windirent.h @@ -13,13 +13,17 @@ ** POSIX functions on Win32 using the MSVCRT. */ -#if defined(_WIN32) && defined(_MSC_VER) +#if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) +#define SQLITE_WINDIRENT_H /* ** We need several data types from the Windows SDK header. */ +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif + #include "windows.h" /* @@ -37,6 +41,33 @@ #include #include #include +#include +#include + +/* +** We may need several defines that should have been in "sys/stat.h". +*/ + +#ifndef S_ISREG +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif + +#ifndef S_ISLNK +#define S_ISLNK(mode) (0) +#endif + +/* +** We may need to provide the "mode_t" type. +*/ + +#ifndef MODE_T_DEFINED + #define MODE_T_DEFINED + typedef unsigned short mode_t; +#endif /* ** We may need to provide the "ino_t" type. @@ -75,22 +106,27 @@ ** We need to provide the necessary structures and related types. */ +#ifndef DIRENT_DEFINED +#define DIRENT_DEFINED typedef struct DIRENT DIRENT; -typedef struct DIR DIR; typedef DIRENT *LPDIRENT; -typedef DIR *LPDIR; - struct DIRENT { ino_t d_ino; /* Sequence number, do not use. */ unsigned d_attributes; /* Win32 file attributes. */ char d_name[NAME_MAX + 1]; /* Name within the directory. */ }; +#endif +#ifndef DIR_DEFINED +#define DIR_DEFINED +typedef struct DIR DIR; +typedef DIR *LPDIR; struct DIR { intptr_t d_handle; /* Value returned by "_findfirst". */ DIRENT d_first; /* DIRENT constructed based on "_findfirst". */ DIRENT d_next; /* DIRENT constructed based on "_findnext". */ }; +#endif /* ** Provide a macro, for use by the implementation, to determine if a diff --git a/src/test_window.c b/src/test_window.c new file mode 100644 index 0000000000..48ab022116 --- /dev/null +++ b/src/test_window.c @@ -0,0 +1,349 @@ +/* +** 2018 June 17 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#include "sqlite3.h" + +#ifdef SQLITE_TEST + +#include "sqliteInt.h" +#include + +extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); +extern const char *sqlite3ErrName(int); + +typedef struct TestWindow TestWindow; +struct TestWindow { + Tcl_Obj *xStep; + Tcl_Obj *xFinal; + Tcl_Obj *xValue; + Tcl_Obj *xInverse; + Tcl_Interp *interp; +}; + +typedef struct TestWindowCtx TestWindowCtx; +struct TestWindowCtx { + Tcl_Obj *pVal; +}; + +static void doTestWindowStep( + int bInverse, + sqlite3_context *ctx, + int nArg, + sqlite3_value **apArg +){ + int i; + TestWindow *p = (TestWindow*)sqlite3_user_data(ctx); + Tcl_Obj *pEval = Tcl_DuplicateObj(bInverse ? p->xInverse : p->xStep); + TestWindowCtx *pCtx = sqlite3_aggregate_context(ctx, sizeof(TestWindowCtx)); + + Tcl_IncrRefCount(pEval); + if( pCtx ){ + const char *zResult; + int rc; + if( pCtx->pVal ){ + Tcl_ListObjAppendElement(p->interp, pEval, Tcl_DuplicateObj(pCtx->pVal)); + }else{ + Tcl_ListObjAppendElement(p->interp, pEval, Tcl_NewStringObj("", -1)); + } + for(i=0; iinterp, pEval, pArg); + } + rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL); + if( rc!=TCL_OK ){ + zResult = Tcl_GetStringResult(p->interp); + sqlite3_result_error(ctx, zResult, -1); + }else{ + if( pCtx->pVal ) Tcl_DecrRefCount(pCtx->pVal); + pCtx->pVal = Tcl_DuplicateObj(Tcl_GetObjResult(p->interp)); + Tcl_IncrRefCount(pCtx->pVal); + } + } + Tcl_DecrRefCount(pEval); +} + +static void doTestWindowFinalize(int bValue, sqlite3_context *ctx){ + TestWindow *p = (TestWindow*)sqlite3_user_data(ctx); + Tcl_Obj *pEval = Tcl_DuplicateObj(bValue ? p->xValue : p->xFinal); + TestWindowCtx *pCtx = sqlite3_aggregate_context(ctx, sizeof(TestWindowCtx)); + + Tcl_IncrRefCount(pEval); + if( pCtx ){ + const char *zResult; + int rc; + if( pCtx->pVal ){ + Tcl_ListObjAppendElement(p->interp, pEval, Tcl_DuplicateObj(pCtx->pVal)); + }else{ + Tcl_ListObjAppendElement(p->interp, pEval, Tcl_NewStringObj("", -1)); + } + + rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL); + zResult = Tcl_GetStringResult(p->interp); + if( rc!=TCL_OK ){ + sqlite3_result_error(ctx, zResult, -1); + }else{ + sqlite3_result_text(ctx, zResult, -1, SQLITE_TRANSIENT); + } + + if( bValue==0 ){ + if( pCtx->pVal ) Tcl_DecrRefCount(pCtx->pVal); + pCtx->pVal = 0; + } + } + Tcl_DecrRefCount(pEval); +} + +static void testWindowStep( + sqlite3_context *ctx, + int nArg, + sqlite3_value **apArg +){ + doTestWindowStep(0, ctx, nArg, apArg); +} +static void testWindowInverse( + sqlite3_context *ctx, + int nArg, + sqlite3_value **apArg +){ + doTestWindowStep(1, ctx, nArg, apArg); +} + +static void testWindowFinal(sqlite3_context *ctx){ + doTestWindowFinalize(0, ctx); +} +static void testWindowValue(sqlite3_context *ctx){ + doTestWindowFinalize(1, ctx); +} + +static void testWindowDestroy(void *pCtx){ + ckfree(pCtx); +} + +/* +** Usage: sqlite3_create_window_function DB NAME XSTEP XFINAL XVALUE XINVERSE +*/ +static int SQLITE_TCLAPI test_create_window( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + TestWindow *pNew; + sqlite3 *db; + const char *zName; + int rc; + + if( objc!=7 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB NAME XSTEP XFINAL XVALUE XINVERSE"); + return TCL_ERROR; + } + + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + zName = Tcl_GetString(objv[2]); + pNew = (TestWindow*)ckalloc(sizeof(TestWindow)); + memset(pNew, 0, sizeof(TestWindow)); + pNew->xStep = Tcl_DuplicateObj(objv[3]); + pNew->xFinal = Tcl_DuplicateObj(objv[4]); + pNew->xValue = Tcl_DuplicateObj(objv[5]); + pNew->xInverse = Tcl_DuplicateObj(objv[6]); + pNew->interp = interp; + + Tcl_IncrRefCount(pNew->xStep); + Tcl_IncrRefCount(pNew->xFinal); + Tcl_IncrRefCount(pNew->xValue); + Tcl_IncrRefCount(pNew->xInverse); + + rc = sqlite3_create_window_function(db, zName, -1, SQLITE_UTF8, (void*)pNew, + testWindowStep, testWindowFinal, testWindowValue, testWindowInverse, + testWindowDestroy + ); + if( rc!=SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_ERROR; + } + + return TCL_OK; +} + +static int SQLITE_TCLAPI test_create_window_misuse( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int rc; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + + rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0, + 0, testWindowFinal, testWindowValue, testWindowInverse, + 0 + ); + if( rc!=SQLITE_MISUSE ) goto error; + rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0, + testWindowStep, 0, testWindowValue, testWindowInverse, + 0 + ); + if( rc!=SQLITE_MISUSE ) goto error; + rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0, + testWindowStep, testWindowFinal, 0, testWindowInverse, + 0 + ); + if( rc!=SQLITE_MISUSE ) goto error; + rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0, + testWindowStep, testWindowFinal, testWindowValue, 0, + 0 + ); + if( rc!=SQLITE_MISUSE ) goto error; + + return TCL_OK; + + error: + Tcl_SetObjResult(interp, Tcl_NewStringObj("misuse test error", -1)); + return TCL_ERROR; +} + +/* +** xStep for sumint(). +*/ +static void sumintStep( + sqlite3_context *ctx, + int nArg, + sqlite3_value *apArg[] +){ + sqlite3_int64 *pInt; + + assert( nArg==1 ); + if( sqlite3_value_type(apArg[0])!=SQLITE_INTEGER ){ + sqlite3_result_error(ctx, "invalid argument", -1); + return; + } + pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, sizeof(sqlite3_int64)); + if( pInt ){ + *pInt += sqlite3_value_int64(apArg[0]); + } +} + +/* +** xInverse for sumint(). +*/ +static void sumintInverse( + sqlite3_context *ctx, + int nArg, + sqlite3_value *apArg[] +){ + sqlite3_int64 *pInt; + pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, sizeof(sqlite3_int64)); + *pInt -= sqlite3_value_int64(apArg[0]); +} + +/* +** xFinal for sumint(). +*/ +static void sumintFinal(sqlite3_context *ctx){ + sqlite3_int64 res = 0; + sqlite3_int64 *pInt; + pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, 0); + if( pInt ) res = *pInt; + sqlite3_result_int64(ctx, res); +} + +/* +** xValue for sumint(). +*/ +static void sumintValue(sqlite3_context *ctx){ + sqlite3_int64 res = 0; + sqlite3_int64 *pInt; + pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, 0); + if( pInt ) res = *pInt; + sqlite3_result_int64(ctx, res); +} + +static int SQLITE_TCLAPI test_create_sumint( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int rc; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + + rc = sqlite3_create_window_function(db, "sumint", 1, SQLITE_UTF8, 0, + sumintStep, sumintFinal, sumintValue, sumintInverse, + 0 + ); + + if( rc!=SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_ERROR; + } + return TCL_OK; +} + +static int SQLITE_TCLAPI test_override_sum( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int rc; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + + rc = sqlite3_create_function(db, "sum", -1, SQLITE_UTF8, 0, + 0, sumintStep, sumintFinal + ); + + if( rc!=SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_ERROR; + } + return TCL_OK; +} + +int Sqlitetest_window_Init(Tcl_Interp *interp){ + static struct { + char *zName; + Tcl_ObjCmdProc *xProc; + int clientData; + } aObjCmd[] = { + { "sqlite3_create_window_function", test_create_window, 0 }, + { "test_create_window_function_misuse", test_create_window_misuse, 0 }, + { "test_create_sumint", test_create_sumint, 0 }, + { "test_override_sum", test_override_sum, 0 }, + }; + int i; + for(i=0; i=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) #endif -/* Make the IdChar function accessible from ctime.c */ -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +/* Make the IdChar function accessible from ctime.c and alter.c */ int sqlite3IsIdChar(u8 c){ return IdChar(c); } -#endif +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Return the id of the next token in string (*pz). Before returning, set +** (*pz) to point to the byte following the parsed token. +*/ +static int getToken(const unsigned char **pz){ + const unsigned char *z = *pz; + int t; /* Token type to return */ + do { + z += sqlite3GetToken(z, &t); + }while( t==TK_SPACE ); + if( t==TK_ID + || t==TK_STRING + || t==TK_JOIN_KW + || t==TK_WINDOW + || t==TK_OVER + || sqlite3ParserFallback(t)==TK_ID + ){ + t = TK_ID; + } + *pz = z; + return t; +} + +/* +** The following three functions are called immediately after the tokenizer +** reads the keywords WINDOW, OVER and FILTER, respectively, to determine +** whether the token should be treated as a keyword or an SQL identifier. +** This cannot be handled by the usual lemon %fallback method, due to +** the ambiguity in some constructions. e.g. +** +** SELECT sum(x) OVER ... +** +** In the above, "OVER" might be a keyword, or it might be an alias for the +** sum(x) expression. If a "%fallback ID OVER" directive were added to +** grammar, then SQLite would always treat "OVER" as an alias, making it +** impossible to call a window-function without a FILTER clause. +** +** WINDOW is treated as a keyword if: +** +** * the following token is an identifier, or a keyword that can fallback +** to being an identifier, and +** * the token after than one is TK_AS. +** +** OVER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is either TK_LP or an identifier. +** +** FILTER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is TK_LP. +*/ +static int analyzeWindowKeyword(const unsigned char *z){ + int t; + t = getToken(&z); + if( t!=TK_ID ) return TK_ID; + t = getToken(&z); + if( t!=TK_AS ) return TK_ID; + return TK_WINDOW; +} +static int analyzeOverKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP ){ + int t = getToken(&z); + if( t==TK_LP || t==TK_ID ) return TK_OVER; + } + return TK_ID; +} +static int analyzeFilterKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP && getToken(&z)==TK_LP ){ + return TK_FILTER; + } + return TK_ID; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** Return the length (in bytes) of the token that begins at z[0]. @@ -456,6 +531,10 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ i = 1; break; } + case CC_NUL: { + *tokenType = TK_ILLEGAL; + return 0; + } default: { *tokenType = TK_ILLEGAL; return 1; @@ -496,9 +575,9 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ /* sqlite3ParserTrace(stdout, "parser: "); */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK pEngine = &sEngine; - sqlite3ParserInit(pEngine); + sqlite3ParserInit(pEngine, pParse); #else - pEngine = sqlite3ParserAlloc(sqlite3Malloc); + pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse); if( pEngine==0 ){ sqlite3OomFault(db); return SQLITE_NOMEM_BKPT; @@ -509,47 +588,64 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->nVar==0 ); assert( pParse->pVList==0 ); while( 1 ){ - if( zSql[0]!=0 ){ - n = sqlite3GetToken((u8*)zSql, &tokenType); - mxSqlLen -= n; - if( mxSqlLen<0 ){ - pParse->rc = SQLITE_TOOBIG; - break; - } - }else{ - /* Upon reaching the end of input, call the parser two more times - ** with tokens TK_SEMI and 0, in that order. */ - if( lastTokenParsed==TK_SEMI ){ - tokenType = 0; - }else if( lastTokenParsed==0 ){ - break; - }else{ - tokenType = TK_SEMI; - } - zSql -= n; + n = sqlite3GetToken((u8*)zSql, &tokenType); + mxSqlLen -= n; + if( mxSqlLen<0 ){ + pParse->rc = SQLITE_TOOBIG; + break; } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( tokenType>=TK_WINDOW ){ + assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER + || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW + ); +#else if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); +#endif /* SQLITE_OMIT_WINDOWFUNC */ if( db->u1.isInterrupted ){ pParse->rc = SQLITE_INTERRUPT; break; } - if( tokenType==TK_ILLEGAL ){ + if( tokenType==TK_SPACE ){ + zSql += n; + continue; + } + if( zSql[0]==0 ){ + /* Upon reaching the end of input, call the parser two more times + ** with tokens TK_SEMI and 0, in that order. */ + if( lastTokenParsed==TK_SEMI ){ + tokenType = 0; + }else if( lastTokenParsed==0 ){ + break; + }else{ + tokenType = TK_SEMI; + } + n = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + }else if( tokenType==TK_WINDOW ){ + assert( n==6 ); + tokenType = analyzeWindowKeyword((const u8*)&zSql[6]); + }else if( tokenType==TK_OVER ){ + assert( n==4 ); + tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); + }else if( tokenType==TK_FILTER ){ + assert( n==6 ); + tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); +#endif /* SQLITE_OMIT_WINDOWFUNC */ + }else{ sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); break; } - zSql += n; - }else{ - pParse->sLastToken.z = zSql; - pParse->sLastToken.n = n; - sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse); - lastTokenParsed = tokenType; - zSql += n; - if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; } + pParse->sLastToken.z = zSql; + pParse->sLastToken.n = n; + sqlite3Parser(pEngine, tokenType, pParse->sLastToken); + lastTokenParsed = tokenType; + zSql += n; + if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; } assert( nErr==0 ); - pParse->zTail = zSql; #ifdef YYTRACKMAXSTACKDEPTH sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, @@ -571,10 +667,12 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pzErrMsg!=0 ); if( pParse->zErrMsg ){ *pzErrMsg = pParse->zErrMsg; - sqlite3_log(pParse->rc, "%s", *pzErrMsg); + sqlite3_log(pParse->rc, "%s in \"%s\"", + *pzErrMsg, pParse->zTail); pParse->zErrMsg = 0; nErr++; } + pParse->zTail = zSql; if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ sqlite3VdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; @@ -590,16 +688,18 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ sqlite3_free(pParse->apVtabLock); #endif - if( !IN_DECLARE_VTAB ){ + if( !IN_SPECIAL_PARSE ){ /* If the pParse->declareVtab flag is set, do not delete any table ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(db, pParse->pNewTable); } + if( !IN_RENAME_OBJECT ){ + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + } if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); - sqlite3DeleteTrigger(db, pParse->pNewTrigger); sqlite3DbFree(db, pParse->pVList); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; diff --git a/src/treeview.c b/src/treeview.c index ba9fa7b2f0..c8c3b90be1 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -58,15 +58,17 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); if( p ){ for(i=0; iiLevel && ibLine)-1; i++){ - sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); + sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4); } - sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); + sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); + } + if( zFormat!=0 ){ + va_start(ap, zFormat); + sqlite3_str_vappendf(&acc, zFormat, ap); + va_end(ap); + assert( acc.nChar>0 ); + sqlite3_str_append(&acc, "\n", 1); } - va_start(ap, zFormat); - sqlite3VXPrintf(&acc, zFormat, ap); - va_end(ap); - assert( acc.nChar>0 ); - if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); sqlite3StrAccumFinish(&acc); fprintf(stdout,"%s", zBuf); fflush(stdout); @@ -99,17 +101,17 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ char zLine[1000]; const struct Cte *pCte = &pWith->a[i]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3XPrintf(&x, "%s", pCte->zName); + sqlite3_str_appendf(&x, "%s", pCte->zName); if( pCte->pCols && pCte->pCols->nExpr>0 ){ char cSep = '('; int j; for(j=0; jpCols->nExpr; j++){ - sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); + sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); cSep = ','; } - sqlite3XPrintf(&x, ")"); + sqlite3_str_appendf(&x, ")"); } - sqlite3XPrintf(&x, " AS"); + sqlite3_str_appendf(&x, " AS"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -137,9 +139,11 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ sqlite3TreeViewPush(pView, 1); } do{ - sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d", + sqlite3TreeViewLine(pView, + "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d", ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), - ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags, + ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), + p->selId, p, p->selFlags, (int)p->nSelectRow ); if( cnt++ ) sqlite3TreeViewPop(pView); @@ -153,9 +157,23 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( p->pHaving ) n++; if( p->pOrderBy ) n++; if( p->pLimit ) n++; - if( p->pOffset ) n++; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ) n++; + if( p->pWinDefn ) n++; +#endif } sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set"); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + Window *pX; + pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewLine(pView, "window-functions"); + for(pX=p->pWin; pX; pX=pX->pNextWin){ + sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(pView); + } +#endif if( p->pSrc && p->pSrc->nSrc ){ int i; pView = sqlite3TreeViewPush(pView, (n--)>0); @@ -165,20 +183,20 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor); + sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor); if( pItem->zDatabase ){ - sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName); + sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); }else if( pItem->zName ){ - sqlite3XPrintf(&x, " %s", pItem->zName); + sqlite3_str_appendf(&x, " %s", pItem->zName); } if( pItem->pTab ){ - sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName); + sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName); } if( pItem->zAlias ){ - sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias); + sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); } if( pItem->fg.jointype & JT_LEFT ){ - sqlite3XPrintf(&x, " LEFT-JOIN"); + sqlite3_str_appendf(&x, " LEFT-JOIN"); } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1); @@ -205,17 +223,27 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ sqlite3TreeViewExpr(pView, p->pHaving, 0); sqlite3TreeViewPop(pView); } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWinDefn ){ + Window *pX; + sqlite3TreeViewItem(pView, "WINDOW", (n--)>0); + for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ + sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(pView); + } +#endif if( p->pOrderBy ){ sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); } if( p->pLimit ){ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); - sqlite3TreeViewExpr(pView, p->pLimit, 0); - sqlite3TreeViewPop(pView); - } - if( p->pOffset ){ - sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); - sqlite3TreeViewExpr(pView, p->pOffset, 0); + sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); + if( p->pLimit->pRight ){ + sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); + sqlite3TreeViewPop(pView); + } sqlite3TreeViewPop(pView); } if( p->pPrior ){ @@ -232,6 +260,83 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ sqlite3TreeViewPop(pView); } +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a description of starting or stopping bounds +*/ +void sqlite3TreeViewBound( + TreeView *pView, /* View context */ + u8 eBound, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */ + Expr *pExpr, /* Value for PRECEDING or FOLLOWING */ + u8 moreToFollow /* True if more to follow */ +){ + switch( eBound ){ + case TK_UNBOUNDED: { + sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); + sqlite3TreeViewPop(pView); + break; + } + case TK_CURRENT: { + sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); + sqlite3TreeViewPop(pView); + break; + } + case TK_PRECEDING: { + sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(pView); + break; + } + case TK_FOLLOWING: { + sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(pView); + break; + } + } +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window object +*/ +void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ + pView = sqlite3TreeViewPush(pView, more); + if( pWin->zName ){ + sqlite3TreeViewLine(pView, "OVER %s", pWin->zName); + }else{ + sqlite3TreeViewLine(pView, "OVER"); + } + if( pWin->pPartition ){ + sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY"); + } + if( pWin->pOrderBy ){ + sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY"); + } + if( pWin->eType ){ + sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0); + sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); + sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); + sqlite3TreeViewPop(pView); + } + sqlite3TreeViewPop(pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window Function object +*/ +void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ + pView = sqlite3TreeViewPush(pView, more); + sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", + pWin->pFunc->zName, pWin->pFunc->nArg); + sqlite3TreeViewWindow(pView, pWin, 0); + sqlite3TreeViewPop(pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + /* ** Generate a human-readable explanation of an expression tree. */ @@ -269,6 +374,9 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewLine(pView, "{%d:%d}%s", pExpr->iTable, pExpr->iColumn, zFlgs); } + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + } break; } case TK_INTEGER: { @@ -293,6 +401,11 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewLine(pView,"NULL"); break; } + case TK_TRUEFALSE: { + sqlite3TreeViewLine(pView, + sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE"); + break; + } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); @@ -349,6 +462,19 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ case TK_ISNULL: zUniOp = "ISNULL"; break; case TK_NOTNULL: zUniOp = "NOTNULL"; break; + case TK_TRUTH: { + int x; + const char *azOp[] = { + "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE" + }; + assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); + assert( pExpr->pRight ); + assert( pExpr->pRight->op==TK_TRUEFALSE ); + x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); + zUniOp = azOp[x]; + break; + } + case TK_SPAN: { sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); @@ -364,10 +490,17 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ case TK_AGG_FUNCTION: case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ + Window *pWin; if( ExprHasProperty(pExpr, EP_TokenOnly) ){ pFarg = 0; + pWin = 0; }else{ pFarg = pExpr->x.pList; +#ifndef SQLITE_OMIT_WINDOWFUNC + pWin = pExpr->y.pWin; +#else + pWin = 0; +#endif } if( pExpr->op==TK_AGG_FUNCTION ){ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q", @@ -376,8 +509,13 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken); } if( pFarg ){ - sqlite3TreeViewExprList(pView, pFarg, 0, 0); + sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + sqlite3TreeViewWindow(pView, pWin, 0); + } +#endif break; } #ifndef SQLITE_OMIT_SUBQUERY @@ -508,12 +646,25 @@ void sqlite3TreeViewBareExprList( sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; inExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; - if( j ){ - sqlite3TreeViewPush(pView, 0); - sqlite3TreeViewLine(pView, "iOrderByCol=%d", j); + char *zName = pList->a[i].zName; + int moreToFollow = inExpr - 1; + if( j || zName ){ + sqlite3TreeViewPush(pView, moreToFollow); + moreToFollow = 0; + sqlite3TreeViewLine(pView, 0); + if( zName ){ + fprintf(stdout, "AS %s ", zName); + } + if( j ){ + fprintf(stdout, "iOrderByCol=%d", j); + } + fprintf(stdout, "\n"); + fflush(stdout); + } + sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); + if( j || zName ){ + sqlite3TreeViewPop(pView); } - sqlite3TreeViewExpr(pView, pList->a[i].pExpr, inExpr-1); - if( j ) sqlite3TreeViewPop(pView); } } } diff --git a/src/trigger.c b/src/trigger.c index 450ebfff67..1d5eafbef6 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -25,6 +25,8 @@ void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){ sqlite3ExprListDelete(db, pTmp->pExprList); sqlite3SelectDelete(db, pTmp->pSelect); sqlite3IdListDelete(db, pTmp->pIdList); + sqlite3UpsertDelete(db, pTmp->pUpsert); + sqlite3DbFree(db, pTmp->zSpan); sqlite3DbFree(db, pTmp); } @@ -179,14 +181,16 @@ void sqlite3BeginTrigger( goto trigger_cleanup; } assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ - if( !noErr ){ - sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); - }else{ - assert( !db->init.busy ); - sqlite3CodeVerifySchema(pParse, iDb); + if( !IN_RENAME_OBJECT ){ + if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } + goto trigger_cleanup; } - goto trigger_cleanup; } /* Do not create a trigger on a system table */ @@ -210,7 +214,7 @@ void sqlite3BeginTrigger( } #ifndef SQLITE_OMIT_AUTHORIZATION - { + if( !IN_RENAME_OBJECT ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int code = SQLITE_CREATE_TRIGGER; const char *zDb = db->aDb[iTabDb].zDbSName; @@ -244,8 +248,15 @@ void sqlite3BeginTrigger( pTrigger->pTabSchema = pTab->pSchema; pTrigger->op = (u8)op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; - pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); - pTrigger->pColumns = sqlite3IdListDup(db, pColumns); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); + pTrigger->pWhen = pWhen; + pWhen = 0; + }else{ + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + pTrigger->pColumns = pColumns; + pColumns = 0; assert( pParse->pNewTrigger==0 ); pParse->pNewTrigger = pTrigger; @@ -294,6 +305,14 @@ void sqlite3FinishTrigger( goto triggerfinish_cleanup; } +#ifndef SQLITE_OMIT_ALTERTABLE + if( IN_RENAME_OBJECT ){ + assert( !db->init.busy ); + pParse->pNewTrigger = pTrig; + pTrig = 0; + }else +#endif + /* if we are not initializing, ** build the sqlite_master entry */ @@ -335,10 +354,21 @@ void sqlite3FinishTrigger( triggerfinish_cleanup: sqlite3DeleteTrigger(db, pTrig); - assert( !pParse->pNewTrigger ); + assert( IN_RENAME_OBJECT || !pParse->pNewTrigger ); sqlite3DeleteTriggerStep(db, pStepList); } +/* +** Duplicate a range of text from an SQL statement, then convert all +** whitespace characters into ordinary space characters. +*/ +static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ + char *z = sqlite3DbSpanDup(db, zStart, zEnd); + int i; + if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' '; + return z; +} + /* ** Turn a SELECT statement (that the pSelect parameter points to) into ** a trigger step. Return a pointer to a TriggerStep structure. @@ -346,7 +376,12 @@ triggerfinish_cleanup: ** The parser calls this routine when it finds a SELECT statement in ** body of a TRIGGER. */ -TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ +TriggerStep *sqlite3TriggerSelectStep( + sqlite3 *db, /* Database connection */ + Select *pSelect, /* The SELECT statement */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); if( pTriggerStep==0 ) { sqlite3SelectDelete(db, pSelect); @@ -355,6 +390,7 @@ TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ pTriggerStep->op = TK_SELECT; pTriggerStep->pSelect = pSelect; pTriggerStep->orconf = OE_Default; + pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); return pTriggerStep; } @@ -365,10 +401,13 @@ TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ ** If an OOM error occurs, NULL is returned and db->mallocFailed is set. */ static TriggerStep *triggerStepAllocate( - sqlite3 *db, /* Database connection */ + Parse *pParse, /* Parser context */ u8 op, /* Trigger opcode */ - Token *pName /* The target name */ + Token *pName, /* The target name */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); @@ -378,6 +417,10 @@ static TriggerStep *triggerStepAllocate( sqlite3Dequote(z); pTriggerStep->zTarget = z; pTriggerStep->op = op; + pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); + } } return pTriggerStep; } @@ -390,23 +433,36 @@ static TriggerStep *triggerStepAllocate( ** body of a trigger. */ TriggerStep *sqlite3TriggerInsertStep( - sqlite3 *db, /* The database connection */ + Parse *pParse, /* Parser */ Token *pTableName, /* Name of the table into which we insert */ IdList *pColumn, /* List of columns in pTableName to insert into */ Select *pSelect, /* A SELECT statement that supplies values */ - u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ + u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ + Upsert *pUpsert, /* ON CONFLICT clauses for upsert */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; assert(pSelect != 0 || db->mallocFailed); - pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName); + pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd); if( pTriggerStep ){ - pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + pTriggerStep->pSelect = pSelect; + pSelect = 0; + }else{ + pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } pTriggerStep->pIdList = pColumn; + pTriggerStep->pUpsert = pUpsert; pTriggerStep->orconf = orconf; }else{ + testcase( pColumn ); sqlite3IdListDelete(db, pColumn); + testcase( pUpsert ); + sqlite3UpsertDelete(db, pUpsert); } sqlite3SelectDelete(db, pSelect); @@ -419,18 +475,28 @@ TriggerStep *sqlite3TriggerInsertStep( ** sees an UPDATE statement inside the body of a CREATE TRIGGER. */ TriggerStep *sqlite3TriggerUpdateStep( - sqlite3 *db, /* The database connection */ + Parse *pParse, /* Parser */ Token *pTableName, /* Name of the table to be updated */ ExprList *pEList, /* The SET clause: list of column and new values */ Expr *pWhere, /* The WHERE clause */ - u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ + u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; - pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName); + pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); if( pTriggerStep ){ - pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); - pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + pTriggerStep->pExprList = pEList; + pTriggerStep->pWhere = pWhere; + pEList = 0; + pWhere = 0; + }else{ + pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + } pTriggerStep->orconf = orconf; } sqlite3ExprListDelete(db, pEList); @@ -444,15 +510,23 @@ TriggerStep *sqlite3TriggerUpdateStep( ** sees a DELETE statement inside the body of a CREATE TRIGGER. */ TriggerStep *sqlite3TriggerDeleteStep( - sqlite3 *db, /* Database connection */ + Parse *pParse, /* Parser */ Token *pTableName, /* The table from which rows are deleted */ - Expr *pWhere /* The WHERE clause */ + Expr *pWhere, /* The WHERE clause */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; - pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName); + pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); if( pTriggerStep ){ - pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + pTriggerStep->pWhere = pWhere; + pWhere = 0; + }else{ + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + } pTriggerStep->orconf = OE_Default; } sqlite3ExprDelete(db, pWhere); @@ -706,13 +780,21 @@ static int codeTriggerProgram( pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; assert( pParse->okConstFactor==0 ); +#ifndef SQLITE_OMIT_TRACE + if( pStep->zSpan ){ + sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0, + sqlite3MPrintf(db, "-- %s", pStep->zSpan), + P4_DYNAMIC); + } +#endif + switch( pStep->op ){ case TK_UPDATE: { sqlite3Update(pParse, targetSrcList(pParse, pStep), sqlite3ExprListDup(db, pStep->pExprList, 0), sqlite3ExprDup(db, pStep->pWhere, 0), - pParse->eOrconf + pParse->eOrconf, 0, 0, 0 ); break; } @@ -721,14 +803,15 @@ static int codeTriggerProgram( targetSrcList(pParse, pStep), sqlite3SelectDup(db, pStep->pSelect, 0), sqlite3IdListDup(db, pStep->pIdList), - pParse->eOrconf + pParse->eOrconf, + sqlite3UpsertDup(db, pStep->pUpsert) ); break; } case TK_DELETE: { sqlite3DeleteFrom(pParse, targetSrcList(pParse, pStep), - sqlite3ExprDup(db, pStep->pWhere, 0) + sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 ); break; } @@ -846,9 +929,11 @@ static TriggerPrg *codeRowTrigger( pTab->zName )); #ifndef SQLITE_OMIT_TRACE - sqlite3VdbeChangeP4(v, -1, - sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC - ); + if( pTrigger->zName ){ + sqlite3VdbeChangeP4(v, -1, + sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC + ); + } #endif /* If one was specified, code the WHEN clause. If it evaluates to false @@ -876,7 +961,7 @@ static TriggerPrg *codeRowTrigger( VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); transferParseError(pParse, pSubParse); - if( db->mallocFailed==0 ){ + if( db->mallocFailed==0 && pParse->nErr==0 ){ pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } pProgram->nMem = pSubParse->nMem; diff --git a/src/update.c b/src/update.c index fa8885be66..70f4f676da 100644 --- a/src/update.c +++ b/src/update.c @@ -79,6 +79,57 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ #endif } +/* +** Check to see if column iCol of index pIdx references any of the +** columns defined by aXRef and chngRowid. Return true if it does +** and false if not. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexColumnIsBeingUpdated( + Index *pIdx, /* The index to check */ + int iCol, /* Which column of the index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + i16 iIdxCol = pIdx->aiColumn[iCol]; + assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */ + if( iIdxCol>=0 ){ + return aXRef[iIdxCol]>=0; + } + assert( iIdxCol==XN_EXPR ); + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->a[iCol].pExpr!=0 ); + return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr, + aXRef,chngRowid); +} + +/* +** Check to see if index pIdx is a partial index whose conditional +** expression might change values due to an UPDATE. Return true if +** the index is subject to change and false if the index is guaranteed +** to be unchanged. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexWhereClauseMightChange( + Index *pIdx, /* The index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + if( pIdx->pPartIdxWhere==0 ) return 0; + return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, + aXRef, chngRowid); +} + /* ** Process an UPDATE statement. ** @@ -91,7 +142,10 @@ void sqlite3Update( SrcList *pTabList, /* The table in which we should change things */ ExprList *pChanges, /* Things to be changed */ Expr *pWhere, /* The WHERE clause. May be null */ - int onError /* How to handle constraint errors */ + int onError, /* How to handle constraint errors */ + ExprList *pOrderBy, /* ORDER BY clause. May be null */ + Expr *pLimit, /* LIMIT clause. May be null */ + Upsert *pUpsert /* ON CONFLICT clause, or null */ ){ int i, j; /* Loop counters */ Table *pTab; /* The table to be updated */ @@ -176,6 +230,16 @@ void sqlite3Update( # define isView 0 #endif +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( !isView ){ + pWhere = sqlite3LimitWhere( + pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE" + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto update_cleanup; } @@ -188,16 +252,23 @@ void sqlite3Update( ** need to occur right after the database cursor. So go ahead and ** allocate enough space, just in case. */ - pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++; + iBaseCur = iDataCur = pParse->nTab++; iIdxCur = iDataCur+1; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + testcase( pPk!=0 && pPk!=pTab->pIndex ); for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ - if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){ + if( pPk==pIdx ){ iDataCur = pParse->nTab; - pTabList->a[0].iCursor = iDataCur; } pParse->nTab++; } + if( pUpsert ){ + /* On an UPSERT, reuse the same cursors already opened by INSERT */ + iDataCur = pUpsert->iDataCur; + iIdxCur = pUpsert->iIdxCur; + pParse->nTab = iBaseCur; + } + pTabList->a[0].iCursor = iDataCur; /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. ** Initialize aXRef[] and aToOpen[] to their default values. @@ -214,6 +285,8 @@ void sqlite3Update( memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; + sNC.uNC.pUpsert = pUpsert; + sNC.ncFlags = NC_UUpsert; /* Resolve the column names in all the expressions of the ** of the UPDATE statement. Also find the column index @@ -280,19 +353,18 @@ void sqlite3Update( /* There is one entry in the aRegIdx[] array for each index on the table ** being updated. Fill in aRegIdx[] with a register number that will hold ** the key for accessing each index. - ** - ** FIXME: Be smarter about omitting indexes that use expressions. */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; - if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){ + if( chngKey || hasFK>1 || pIdx==pPk + || indexWhereClauseMightChange(pIdx,aXRef,chngRowid) + ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; }else{ reg = 0; for(i=0; inKeyCol; i++){ - i16 iIdxCol = pIdx->aiColumn[i]; - if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){ + if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; if( (onError==OE_Replace) @@ -317,7 +389,7 @@ void sqlite3Update( v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb); /* Allocate required registers. */ if( !IsVirtual(pTab) ){ @@ -344,7 +416,11 @@ void sqlite3Update( */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ - sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur); + sqlite3MaterializeView(pParse, pTab, + pWhere, pOrderBy, pLimit, iDataCur + ); + pOrderBy = 0; + pLimit = 0; } #endif @@ -364,8 +440,16 @@ void sqlite3Update( } #endif - /* Initialize the count of updated rows */ - if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){ + /* Jump to labelBreak to abandon further processing of this UPDATE */ + labelContinue = labelBreak = sqlite3VdbeMakeLabel(v); + + /* Not an UPSERT. Normal processing. Begin by + ** initialize the count of updated rows */ + if( (db->flags&SQLITE_CountRows)!=0 + && !pParse->pTriggerTab + && !pParse->nested + && pUpsert==0 + ){ regRowCount = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); } @@ -378,46 +462,61 @@ void sqlite3Update( iPk = pParse->nMem+1; pParse->nMem += nPk; regKey = ++pParse->nMem; - iEph = pParse->nTab++; - - sqlite3VdbeAddOp2(v, OP_Null, 0, iPk); - addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); - sqlite3VdbeSetP4KeyInfo(pParse, pPk); - } - - /* Begin the database scan. - ** - ** Do not consider a single-pass strategy for a multi-row update if - ** there are any triggers or foreign keys to process, or rows may - ** be deleted as a result of REPLACE conflict handling. Any of these - ** things might disturb a cursor being used to scan through the table - ** or index, causing a single-pass approach to malfunction. */ - flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE; - if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ - flags |= WHERE_ONEPASS_MULTIROW; - } - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); - if( pWInfo==0 ) goto update_cleanup; - - /* A one-pass strategy that might update more than one row may not - ** be used if any column of the index used for the scan is being - ** updated. Otherwise, if there is an index on "b", statements like - ** the following could create an infinite loop: - ** - ** UPDATE t1 SET b=b+1 WHERE b>? - ** - ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI - ** strategy that uses an index for which one or more columns are being - ** updated. */ - eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - if( eOnePass==ONEPASS_MULTI ){ - int iCur = aiCurOnePass[1]; - if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ - eOnePass = ONEPASS_OFF; + if( pUpsert==0 ){ + iEph = pParse->nTab++; + sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1); + addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); } - assert( iCur!=iDataCur || !HasRowid(pTab) ); } + if( pUpsert ){ + /* If this is an UPSERT, then all cursors have already been opened by + ** the outer INSERT and the data cursor should be pointing at the row + ** that is to be updated. So bypass the code that searches for the + ** row(s) to be updated. + */ + pWInfo = 0; + eOnePass = ONEPASS_SINGLE; + sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); + }else{ + /* Begin the database scan. + ** + ** Do not consider a single-pass strategy for a multi-row update if + ** there are any triggers or foreign keys to process, or rows may + ** be deleted as a result of REPLACE conflict handling. Any of these + ** things might disturb a cursor being used to scan through the table + ** or index, causing a single-pass approach to malfunction. */ + flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE; + if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ + flags |= WHERE_ONEPASS_MULTIROW; + } + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); + if( pWInfo==0 ) goto update_cleanup; + + /* A one-pass strategy that might update more than one row may not + ** be used if any column of the index used for the scan is being + ** updated. Otherwise, if there is an index on "b", statements like + ** the following could create an infinite loop: + ** + ** UPDATE t1 SET b=b+1 WHERE b>? + ** + ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI + ** strategy that uses an index for which one or more columns are being + ** updated. */ + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + if( eOnePass!=ONEPASS_SINGLE ){ + sqlite3MultiWrite(pParse); + if( eOnePass==ONEPASS_MULTI ){ + int iCur = aiCurOnePass[1]; + if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ + eOnePass = ONEPASS_OFF; + } + assert( iCur!=iDataCur || !HasRowid(pTab) ); + } + } + } + if( HasRowid(pTab) ){ /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF ** mode, write the rowid into the FIFO. In either of the one-pass modes, @@ -437,7 +536,7 @@ void sqlite3Update( sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i); } if( eOnePass ){ - sqlite3VdbeChangeToNoop(v, addrOpen); + if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen); nKey = nPk; regKey = iPk; }else{ @@ -447,59 +546,58 @@ void sqlite3Update( } } - if( eOnePass!=ONEPASS_MULTI ){ - sqlite3WhereEnd(pWInfo); - } - - labelBreak = sqlite3VdbeMakeLabel(v); - if( !isView ){ - int addrOnce = 0; - - /* Open every index that needs updating. */ + if( pUpsert==0 ){ + if( eOnePass!=ONEPASS_MULTI ){ + sqlite3WhereEnd(pWInfo); + } + + if( !isView ){ + int addrOnce = 0; + + /* Open every index that needs updating. */ + if( eOnePass!=ONEPASS_OFF ){ + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; + } + + if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, + aToOpen, 0, 0); + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); + } + + /* Top of the update loop */ if( eOnePass!=ONEPASS_OFF ){ - if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; - if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; - } - - if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ - addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - } - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, - 0, 0); - if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); - } - - /* Top of the update loop */ - if( eOnePass!=ONEPASS_OFF ){ - if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ - assert( pPk ); - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); - VdbeCoverageNeverTaken(v); - } - if( eOnePass==ONEPASS_SINGLE ){ - labelContinue = labelBreak; - }else{ + if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ + assert( pPk ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); + VdbeCoverage(v); + } + if( eOnePass!=ONEPASS_SINGLE ){ + labelContinue = sqlite3VdbeMakeLabel(v); + } + sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); + VdbeCoverageIf(v, pPk==0); + VdbeCoverageIf(v, pPk!=0); + }else if( pPk ){ labelContinue = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); + addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); + VdbeCoverage(v); + }else{ + labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak, + regOldRowid); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); + VdbeCoverage(v); } - sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); - VdbeCoverageIf(v, pPk==0); - VdbeCoverageIf(v, pPk!=0); - }else if( pPk ){ - labelContinue = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); - addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); - VdbeCoverage(v); - }else{ - labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak, - regOldRowid); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); - VdbeCoverage(v); } - /* If the record number will change, set register regNewRowid to - ** contain the new value. If the record number is not being modified, + /* If the rowid value will change, set register regNewRowid to + ** contain the new value. If the rowid is not being modified, ** then regNewRowid is the same register as regOldRowid, which is ** already populated. */ assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid ); @@ -562,7 +660,7 @@ void sqlite3Update( */ testcase( i==31 ); testcase( i==32 ); - sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); } @@ -591,10 +689,14 @@ void sqlite3Update( VdbeCoverage(v); } - /* If it did not delete it, the row-trigger may still have modified + /* After-BEFORE-trigger-reload-loop: + ** If it did not delete it, the BEFORE trigger may still have modified ** some of the columns of the row being updated. Load the values for - ** all columns not modified by the update statement into their - ** registers in case this has happened. + ** all columns not modified by the update statement into their registers + ** in case this has happened. Only unmodified columns are reloaded. + ** The values computed for modified columns use the values before the + ** BEFORE trigger runs. See test case trigger1-18.0 (added 2018-04-26) + ** for an example. */ for(i=0; inCol; i++){ if( aXRef[i]<0 && i!=pTab->iPKey ){ @@ -610,7 +712,7 @@ void sqlite3Update( assert( regOldRowid>0 ); sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, - aXRef); + aXRef, 0); /* Do FK constraint checks. */ if( hasFK ){ @@ -680,7 +782,7 @@ void sqlite3Update( /* Increment the row counter */ - if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){ + if( regRowCount ){ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } @@ -707,16 +809,15 @@ void sqlite3Update( ** maximum rowid counter values recorded while inserting into ** autoincrement tables. */ - if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){ sqlite3AutoincrementEnd(pParse); } /* - ** Return the number of rows that were changed. If this routine is - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. + ** Return the number of rows that were changed, if we are tracking + ** that information. */ - if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){ + if( regRowCount ){ sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); @@ -728,6 +829,10 @@ update_cleanup: sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pChanges); sqlite3ExprDelete(db, pWhere); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); +#endif return; } /* Make sure "isView" and other macros defined above are undefined. Otherwise @@ -784,10 +889,10 @@ static void updateVirtualTable( int regRowid; /* Register for ephem table rowid */ int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ - int bOnePass; /* True to use onepass strategy */ + int eOnePass; /* True to use onepass strategy */ int addr; /* Address of OP_OpenEphemeral */ - /* Allocate nArg registers to martial the arguments to VUpdate. Then + /* Allocate nArg registers in which to gather the arguments for VUpdate. Then ** create and open the ephemeral table in which the records created from ** these arguments will be temporarily stored. */ assert( v ); @@ -803,40 +908,58 @@ static void updateVirtualTable( if( pWInfo==0 ) return; /* Populate the argument registers. */ - sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); - if( pRowid ){ - sqlite3ExprCode(pParse, pRowid, regArg+1); - }else{ - sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); - } for(i=0; inCol; i++){ if( aXRef[i]>=0 ){ sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */ } } - - bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); - - if( bOnePass ){ - /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded - ** above. Also, if this is a top-level parse (not a trigger), clear the - ** multi-write flag so that the VM does not open a statement journal */ - sqlite3VdbeChangeToNoop(v, addr); - if( sqlite3IsToplevel(pParse) ){ - pParse->isMultiWrite = 0; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); + if( pRowid ){ + sqlite3ExprCode(pParse, pRowid, regArg+1); + }else{ + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); } + }else{ + Index *pPk; /* PRIMARY KEY index */ + i16 iPk; /* PRIMARY KEY column */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol==1 ); + iPk = pPk->aiColumn[0]; + sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1); + } + + eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); + + /* There is no ONEPASS_MULTI on virtual tables */ + assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); + + if( eOnePass ){ + /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded + ** above. */ + sqlite3VdbeChangeToNoop(v, addr); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); }else{ /* Create a record from the argument register contents and insert it into ** the ephemeral table. */ + sqlite3MultiWrite(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); +#ifdef SQLITE_DEBUG + /* Signal an assert() within OP_MakeRecord that it is allowed to + ** accept no-change records with serial_type 10 */ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); +#endif sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); } - if( bOnePass==0 ){ + if( eOnePass==ONEPASS_OFF ){ /* End the virtual table scan */ sqlite3WhereEnd(pWInfo); @@ -856,7 +979,7 @@ static void updateVirtualTable( /* End of the ephemeral table scan. Or, if using the onepass strategy, ** jump to here if the scan visited zero rows. */ - if( bOnePass==0 ){ + if( eOnePass==ONEPASS_OFF ){ sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); diff --git a/src/upsert.c b/src/upsert.c new file mode 100644 index 0000000000..850ae863b9 --- /dev/null +++ b/src/upsert.c @@ -0,0 +1,252 @@ +/* +** 2018-04-12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code to implement various aspects of UPSERT +** processing and handling of the Upsert object. +*/ +#include "sqliteInt.h" + +#ifndef SQLITE_OMIT_UPSERT +/* +** Free a list of Upsert objects +*/ +void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ + if( p ){ + sqlite3ExprListDelete(db, p->pUpsertTarget); + sqlite3ExprDelete(db, p->pUpsertTargetWhere); + sqlite3ExprListDelete(db, p->pUpsertSet); + sqlite3ExprDelete(db, p->pUpsertWhere); + sqlite3DbFree(db, p); + } +} + +/* +** Duplicate an Upsert object. +*/ +Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ + if( p==0 ) return 0; + return sqlite3UpsertNew(db, + sqlite3ExprListDup(db, p->pUpsertTarget, 0), + sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), + sqlite3ExprListDup(db, p->pUpsertSet, 0), + sqlite3ExprDup(db, p->pUpsertWhere, 0) + ); +} + +/* +** Create a new Upsert object. +*/ +Upsert *sqlite3UpsertNew( + sqlite3 *db, /* Determines which memory allocator to use */ + ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ + Expr *pTargetWhere, /* Optional WHERE clause on the target */ + ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ + Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */ +){ + Upsert *pNew; + pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pTarget); + sqlite3ExprDelete(db, pTargetWhere); + sqlite3ExprListDelete(db, pSet); + sqlite3ExprDelete(db, pWhere); + return 0; + }else{ + pNew->pUpsertTarget = pTarget; + pNew->pUpsertTargetWhere = pTargetWhere; + pNew->pUpsertSet = pSet; + pNew->pUpsertWhere = pWhere; + pNew->pUpsertIdx = 0; + } + return pNew; +} + +/* +** Analyze the ON CONFLICT clause described by pUpsert. Resolve all +** symbols in the conflict-target. +** +** Return SQLITE_OK if everything works, or an error code is something +** is wrong. +*/ +int sqlite3UpsertAnalyzeTarget( + Parse *pParse, /* The parsing context */ + SrcList *pTabList, /* Table into which we are inserting */ + Upsert *pUpsert /* The ON CONFLICT clauses */ +){ + Table *pTab; /* That table into which we are inserting */ + int rc; /* Result code */ + int iCursor; /* Cursor used by pTab */ + Index *pIdx; /* One of the indexes of pTab */ + ExprList *pTarget; /* The conflict-target clause */ + Expr *pTerm; /* One term of the conflict-target clause */ + NameContext sNC; /* Context for resolving symbolic names */ + Expr sCol[2]; /* Index column converted into an Expr */ + + assert( pTabList->nSrc==1 ); + assert( pTabList->a[0].pTab!=0 ); + assert( pUpsert!=0 ); + assert( pUpsert->pUpsertTarget!=0 ); + + /* Resolve all symbolic names in the conflict-target clause, which + ** includes both the list of columns and the optional partial-index + ** WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc ) return rc; + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + if( rc ) return rc; + + /* Check to see if the conflict target matches the rowid. */ + pTab = pTabList->a[0].pTab; + pTarget = pUpsert->pUpsertTarget; + iCursor = pTabList->a[0].iCursor; + if( HasRowid(pTab) + && pTarget->nExpr==1 + && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN + && pTerm->iColumn==XN_ROWID + ){ + /* The conflict-target is the rowid of the primary table */ + assert( pUpsert->pUpsertIdx==0 ); + return SQLITE_OK; + } + + /* Initialize sCol[0..1] to be an expression parse tree for a + ** single column of an index. The sCol[0] node will be the TK_COLLATE + ** operator and sCol[1] will be the TK_COLUMN operator. Code below + ** will populate the specific collation and column number values + ** prior to comparing against the conflict-target expression. + */ + memset(sCol, 0, sizeof(sCol)); + sCol[0].op = TK_COLLATE; + sCol[0].pLeft = &sCol[1]; + sCol[1].op = TK_COLUMN; + sCol[1].iTable = pTabList->a[0].iCursor; + + /* Check for matches against other indexes */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int ii, jj, nn; + if( !IsUniqueIndex(pIdx) ) continue; + if( pTarget->nExpr!=pIdx->nKeyCol ) continue; + if( pIdx->pPartIdxWhere ){ + if( pUpsert->pUpsertTargetWhere==0 ) continue; + if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, + pIdx->pPartIdxWhere, iCursor)!=0 ){ + continue; + } + } + nn = pIdx->nKeyCol; + for(ii=0; iiazColl[ii]; + if( pIdx->aiColumn[ii]==XN_EXPR ){ + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->nExpr>ii ); + pExpr = pIdx->aColExpr->a[ii].pExpr; + if( pExpr->op!=TK_COLLATE ){ + sCol[0].pLeft = pExpr; + pExpr = &sCol[0]; + } + }else{ + sCol[0].pLeft = &sCol[1]; + sCol[1].iColumn = pIdx->aiColumn[ii]; + pExpr = &sCol[0]; + } + for(jj=0; jja[jj].pExpr, pExpr,iCursor)<2 ){ + break; /* Column ii of the index matches column jj of target */ + } + } + if( jj>=nn ){ + /* The target contains no match for column jj of the index */ + break; + } + } + if( iipUpsertIdx = pIdx; + return SQLITE_OK; + } + sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any " + "PRIMARY KEY or UNIQUE constraint"); + return SQLITE_ERROR; +} + +/* +** Generate bytecode that does an UPDATE as part of an upsert. +** +** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK. +** In this case parameter iCur is a cursor open on the table b-tree that +** currently points to the conflicting table row. Otherwise, if pIdx +** is not NULL, then pIdx is the constraint that failed and iCur is a +** cursor points to the conflicting row. +*/ +void sqlite3UpsertDoUpdate( + Parse *pParse, /* The parsing and code-generating context */ + Upsert *pUpsert, /* The ON CONFLICT clause for the upsert */ + Table *pTab, /* The table being updated */ + Index *pIdx, /* The UNIQUE constraint that failed */ + int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */ +){ + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + SrcList *pSrc; /* FROM clause for the UPDATE */ + int iDataCur; + + assert( v!=0 ); + assert( pUpsert!=0 ); + VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); + iDataCur = pUpsert->iDataCur; + if( pIdx && iCur!=iDataCur ){ + if( HasRowid(pTab) ){ + int regRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regRowid); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + int nPk = pPk->nKeyCol; + int iPk = pParse->nMem+1; + int i; + pParse->nMem += nPk; + for(i=0; iaiColumn[i]>=0 ); + k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); + VdbeComment((v, "%s.%s", pIdx->zName, + pTab->aCol[pPk->aiColumn[i]].zName)); + } + sqlite3VdbeVerifyAbortable(v, OE_Abort); + i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); + VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, + "corrupt database", P4_STATIC); + sqlite3VdbeJumpHere(v, i); + } + } + /* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So + ** we have to make a copy before passing it down into sqlite3Update() */ + pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0); + sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, + pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); + pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ + pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */ + VdbeNoopComment((v, "End DO UPDATE of UPSERT")); +} + +#endif /* SQLITE_OMIT_UPSERT */ diff --git a/src/util.c b/src/util.c index 7c9c5f54b7..54f9b93887 100644 --- a/src/util.c +++ b/src/util.c @@ -320,6 +320,45 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; } +/* +** Compute 10 to the E-th power. Examples: E==1 results in 10. +** E==2 results in 100. E==50 results in 1.0e50. +** +** This routine only works for values of E between 1 and 341. +*/ +static LONGDOUBLE_TYPE sqlite3Pow10(int E){ +#if defined(_MSC_VER) + static const LONGDOUBLE_TYPE x[] = { + 1.0e+001, + 1.0e+002, + 1.0e+004, + 1.0e+008, + 1.0e+016, + 1.0e+032, + 1.0e+064, + 1.0e+128, + 1.0e+256 + }; + LONGDOUBLE_TYPE r = 1.0; + int i; + assert( E>=0 && E<=307 ); + for(i=0; E!=0; i++, E >>=1){ + if( E & 1 ) r *= x[i]; + } + return r; +#else + LONGDOUBLE_TYPE x = 10.0; + LONGDOUBLE_TYPE r = 1.0; + while(1){ + if( E & 1 ) r *= x; + E >>= 1; + if( E==0 ) break; + x *= x; + } + return r; +#endif +} + /* ** The string z[] is an text representation of a real number. ** Convert this string to a double and write it into *pResult. @@ -387,12 +426,12 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ /* copy max significant digits to significand */ while( z=zEnd ) goto do_atof_calc; /* if decimal point is present */ @@ -405,7 +444,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ s = s*10 + (*z - '0'); d--; } - z+=incr, nDigits++; + z+=incr; nDigits++; } } if( z>=zEnd ) goto do_atof_calc; @@ -475,11 +514,10 @@ do_atof_calc: if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ result = (double)s; }else{ - LONGDOUBLE_TYPE scale = 1.0; /* attempt to handle extremely small/large numbers better */ if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ - while( e%308 ) { scale *= 1.0e+1; e -= 1; } + LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308); if( esign<0 ){ result = s / scale; result /= 1.0e+308; @@ -491,14 +529,15 @@ do_atof_calc: if( esign<0 ){ result = 0.0*s; }else{ +#ifdef INFINITY + result = INFINITY*s; +#else result = 1e308*1e308*s; /* Infinity */ +#endif } } }else{ - /* 1.0e+22 is the largest power of 10 than can be - ** represented exactly. */ - while( e%22 ) { scale *= 1.0e+1; e -= 1; } - while( e>0 ) { scale *= 1.0e+22; e -= 22; } + LONGDOUBLE_TYPE scale = sqlite3Pow10(e); if( esign<0 ){ result = s / scale; }else{ @@ -553,16 +592,12 @@ static int compare2pow63(const char *zNum, int incr){ ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This ** routine does *not* accept hexadecimal notation. ** -** If the zNum value is representable as a 64-bit twos-complement -** integer, then write that value into *pNum and return 0. +** Returns: ** -** If zNum is exactly 9223372036854775808, return 2. This special -** case is broken out because while 9223372036854775808 cannot be a -** signed 64-bit integer, its negative -9223372036854775808 can be. -** -** If zNum is too big for a 64-bit integer and is not -** 9223372036854775808 or if zNum contains any non-numeric text, -** then return 1. +** 0 Successful transformation. Fits in a 64-bit signed integer. +** 1 Excess non-space text after the integer value +** 2 Integer too large for a 64-bit signed integer or is malformed +** 3 Special case of 9223372036854775808 ** ** length is the number of bytes in the string (bytes, not characters). ** The string is not necessarily zero-terminated. The encoding is @@ -575,6 +610,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int i; int c = 0; int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ + int rc; /* Baseline return code */ const char *zStart; const char *zEnd = zNum + length; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); @@ -602,43 +638,57 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ for(i=0; &zNum[i]='0' && c<='9'; i+=incr){ u = u*10 + c - '0'; } + testcase( i==18*incr ); + testcase( i==19*incr ); + testcase( i==20*incr ); if( u>LARGEST_INT64 ){ + /* This test and assignment is needed only to suppress UB warnings + ** from clang and -fsanitize=undefined. This test and assignment make + ** the code a little larger and slower, and no harm comes from omitting + ** them, but we must appaise the undefined-behavior pharisees. */ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; }else if( neg ){ *pNum = -(i64)u; }else{ *pNum = (i64)u; } - testcase( i==18 ); - testcase( i==19 ); - testcase( i==20 ); - if( &zNum[i]19*incr /* Too many digits */ + rc = 0; + if( (i==0 && zStart==zNum) /* No digits */ || nonNum /* UTF16 with high-order bytes non-zero */ ){ - /* zNum is empty or contains non-numeric text or is longer - ** than 19 digits (thus guaranteeing that it is too large) */ - return 1; - }else if( i<19*incr ){ + rc = 1; + }else if( &zNum[i]19*incr ? 1 : compare2pow63(zNum, incr); if( c<0 ){ /* zNum is less than 9223372036854775808 so it fits */ assert( u<=LARGEST_INT64 ); - return 0; - }else if( c>0 ){ - /* zNum is greater than 9223372036854775808 so it overflows */ - return 1; + return rc; }else{ - /* zNum is exactly 9223372036854775808. Fits if negative. The - ** special case 2 overflow if positive */ - assert( u-1==LARGEST_INT64 ); - return neg ? 0 : 2; + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; + if( c>0 ){ + /* zNum is greater than 9223372036854775808 so it overflows */ + return 2; + }else{ + /* zNum is exactly 9223372036854775808. Fits if negative. The + ** special case 2 overflow if positive */ + assert( u-1==LARGEST_INT64 ); + return neg ? rc : 3; + } } } } @@ -651,8 +701,9 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ ** Returns: ** ** 0 Successful transformation. Fits in a 64-bit signed integer. -** 1 Integer too large for a 64-bit signed integer or is malformed -** 2 Special case of 9223372036854775808 +** 1 Excess text after the integer value +** 2 Integer too large for a 64-bit signed integer or is malformed +** 3 Special case of 9223372036854775808 */ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ #ifndef SQLITE_OMIT_HEX_INTEGER @@ -666,7 +717,7 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ u = u*16 + sqlite3HexToInt(z[k]); } memcpy(pOut, &u, 8); - return (z[k]==0 && k-i<=16) ? 0 : 1; + return (z[k]==0 && k-i<=16) ? 0 : 2; }else #endif /* SQLITE_OMIT_HEX_INTEGER */ { @@ -1276,7 +1327,7 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** overflow, leave *pA unchanged and return 1. */ int sqlite3AddInt64(i64 *pA, i64 iB){ -#if GCC_VERSION>=5004000 +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) return __builtin_add_overflow(*pA, iB, pA); #else i64 iA = *pA; @@ -1296,7 +1347,7 @@ int sqlite3AddInt64(i64 *pA, i64 iB){ #endif } int sqlite3SubInt64(i64 *pA, i64 iB){ -#if GCC_VERSION>=5004000 +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) return __builtin_sub_overflow(*pA, iB, pA); #else testcase( iB==SMALLEST_INT64+1 ); @@ -1311,7 +1362,7 @@ int sqlite3SubInt64(i64 *pA, i64 iB){ #endif } int sqlite3MulInt64(i64 *pA, i64 iB){ -#if GCC_VERSION>=5004000 +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) return __builtin_mul_overflow(*pA, iB, pA); #else i64 iA = *pA; @@ -1413,8 +1464,14 @@ LogEst sqlite3LogEst(u64 x){ if( x<2 ) return 0; while( x<8 ){ y -= 10; x <<= 1; } }else{ +#if GCC_VERSION>=5004000 + int i = 60 - __builtin_clzll(x); + y += i*10; + x >>= i; +#else while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ while( x>15 ){ y += 10; x >>= 1; } +#endif } return a[x&7] + y - 10; } diff --git a/src/vacuum.c b/src/vacuum.c index 133cf63c56..57344bb030 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -39,8 +39,14 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 ); - if( zSubSql ){ - assert( zSubSql[0]!='S' ); + /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX, + ** or INSERT. Historically there have been attacks that first + ** corrupt the sqlite_master.sql field with other kinds of statements + ** then run VACUUM to get those statements to execute at inappropriate + ** times. */ + if( zSubSql + && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0) + ){ rc = execSql(db, pzErrMsg, zSubSql); if( rc!=SQLITE_OK ) break; } @@ -219,7 +225,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ */ rc = execSql(db, pzErrMsg, "BEGIN"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeBeginTrans(pMain, 2); + rc = sqlite3BtreeBeginTrans(pMain, 2, 0); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Do not attempt to change the page size for a WAL database */ @@ -254,7 +260,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = execSqlF(db, pzErrMsg, "SELECT sql FROM \"%w\".sqlite_master" - " WHERE type='index' AND length(sql)>10", + " WHERE type='index'", zDbMain ); if( rc!=SQLITE_OK ) goto end_of_vacuum; diff --git a/src/vdbe.c b/src/vdbe.c index d04a4f2c91..14f3e1bd3c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -122,32 +122,56 @@ int sqlite3_found_count = 0; ** feature is used for test suite validation only and does not appear an ** production builds. ** -** M is an integer, 2 or 3, that indices how many different ways the -** branch can go. It is usually 2. "I" is the direction the branch -** goes. 0 means falls through. 1 means branch is taken. 2 means the -** second alternative branch is taken. +** M is an integer between 2 and 4. 2 indicates a ordinary two-way +** branch (I=0 means fall through and I=1 means taken). 3 indicates +** a 3-way branch where the third way is when one of the operands is +** NULL. 4 indicates the OP_Jump instruction which has three destinations +** depending on whether the first operand is less than, equal to, or greater +** than the second. ** ** iSrcLine is the source code line (from the __LINE__ macro) that -** generated the VDBE instruction. This instrumentation assumes that all -** source code is in a single file (the amalgamation). Special values 1 -** and 2 for the iSrcLine parameter mean that this particular branch is -** always taken or never taken, respectively. +** generated the VDBE instruction combined with flag bits. The source +** code line number is in the lower 24 bits of iSrcLine and the upper +** 8 bytes are flags. The lower three bits of the flags indicate +** values for I that should never occur. For example, if the branch is +** always taken, the flags should be 0x05 since the fall-through and +** alternate branch are never taken. If a branch is never taken then +** flags should be 0x06 since only the fall-through approach is allowed. +** +** Bit 0x04 of the flags indicates an OP_Jump opcode that is only +** interested in equal or not-equal. In other words, I==0 and I==2 +** should be treated the same. +** +** Since only a line number is retained, not the filename, this macro +** only works for amalgamation builds. But that is ok, since these macros +** should be no-ops except for special builds used to measure test coverage. */ #if !defined(SQLITE_VDBE_COVERAGE) # define VdbeBranchTaken(I,M) #else # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) - static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){ - if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){ - M = iSrcLine; - /* Assert the truth of VdbeCoverageAlwaysTaken() and - ** VdbeCoverageNeverTaken() */ - assert( (M & I)==I ); - }else{ - if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ - sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, - iSrcLine,I,M); + static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){ + u8 mNever; + assert( I<=2 ); /* 0: fall through, 1: taken, 2: alternate taken */ + assert( M<=4 ); /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */ + assert( I> 24; + assert( (I & mNever)==0 ); + if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ + I |= mNever; + if( M==2 ) I |= 0x04; + if( M==4 ){ + I |= 0x08; + if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/ } + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, + iSrcLine&0xffffff, I, M); } #endif @@ -264,6 +288,11 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ pRec->flags |= MEM_Real; if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); } + /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the + ** string representation after computing a numeric equivalent, because the + ** string representation might not be the canonical representation for the + ** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */ + pRec->flags &= ~MEM_Str; } /* @@ -354,7 +383,7 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ return 0; } - if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ + if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){ return MEM_Int; } return MEM_Real; @@ -464,7 +493,7 @@ static void memTracePrint(Mem *p){ if( p->flags & MEM_Undefined ){ printf(" undefined"); }else if( p->flags & MEM_Null ){ - printf(" NULL"); + printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ printf(" si:%lld", p->u.i); }else if( p->flags & MEM_Int ){ @@ -473,7 +502,7 @@ static void memTracePrint(Mem *p){ }else if( p->flags & MEM_Real ){ printf(" r:%g", p->u.r); #endif - }else if( p->flags & MEM_RowSet ){ + }else if( sqlite3VdbeMemIsRowSet(p) ){ printf(" (rowset)"); }else{ char zBuf[200]; @@ -643,7 +672,7 @@ int sqlite3VdbeExec( assert( pOp>=aOp && pOp<&aOp[p->nOp]); #ifdef VDBE_PROFILE - start = sqlite3Hwtime(); + start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); #endif nVmStep++; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -910,6 +939,9 @@ case OP_Yield: { /* in1, jump */ */ case OP_HaltIfNull: { /* in3 */ pIn3 = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } +#endif if( (pIn3->flags & MEM_Null)==0 ) break; /* Fall through into OP_Halt */ } @@ -949,6 +981,9 @@ case OP_Halt: { int pcx; pcx = (int)(pOp - aOp); +#ifdef SQLITE_DEBUG + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } +#endif if( pOp->p1==SQLITE_OK && p->pFrame ){ /* Halt the sub-program. Return control to the parent frame. */ pFrame = p->pFrame; @@ -1132,6 +1167,9 @@ case OP_Null: { /* out2 */ assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; pOut->n = 0; +#ifdef SQLITE_DEBUG + pOut->uTemp = 0; +#endif while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); @@ -1253,6 +1291,7 @@ case OP_Copy: { pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); while( 1 ){ + memAboutToChange(p, pOut); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); Deephemeralize(pOut); #ifdef SQLITE_DEBUG @@ -1285,7 +1324,8 @@ case OP_SCopy: { /* out2 */ assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG - if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; + pOut->pScopyFrom = pIn1; + pOut->mScopyFlags = pIn1->flags; #endif break; } @@ -1919,7 +1959,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( (flags1 | flags3)&MEM_Str ){ if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); - testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */ + assert( flags3==pIn3->flags ); + /* testcase( flags3!=pIn3->flags ); + ** this used to be possible with pIn1==pIn3, but not since + ** the column cache was removed. The following assignment + ** is essentially a no-op. But, it provides defense-in-depth + ** in case our analysis is incorrect, so it is left in. */ flags3 = pIn3->flags; } if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ @@ -2133,11 +2178,11 @@ case OP_Compare: { */ case OP_Jump: { /* jump */ if( iCompare<0 ){ - VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1]; + VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; }else if( iCompare==0 ){ - VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1]; + VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1]; }else{ - VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1]; + VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1]; } break; } @@ -2167,18 +2212,8 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ - pIn1 = &aMem[pOp->p1]; - if( pIn1->flags & MEM_Null ){ - v1 = 2; - }else{ - v1 = sqlite3VdbeIntValue(pIn1)!=0; - } - pIn2 = &aMem[pOp->p2]; - if( pIn2->flags & MEM_Null ){ - v2 = 2; - }else{ - v2 = sqlite3VdbeIntValue(pIn2)!=0; - } + v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2); + v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2); if( pOp->opcode==OP_And ){ static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; v1 = and_logic[v1*3+v2]; @@ -2196,6 +2231,35 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ break; } +/* Opcode: IsTrue P1 P2 P3 P4 * +** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 +** +** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and +** IS NOT FALSE operators. +** +** Interpret the value in register P1 as a boolean value. Store that +** boolean (a 0 or 1) in register P2. Or if the value in register P1 is +** NULL, then the P3 is stored in register P2. Invert the answer if P4 +** is 1. +** +** The logic is summarized like this: +** +**
        +**
      • If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE +**
      • If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE +**
      • If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE +**
      • If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE +**
      +*/ +case OP_IsTrue: { /* in1, out2 */ + assert( pOp->p4type==P4_INT32 ); + assert( pOp->p4.i==0 || pOp->p4.i==1 ); + assert( pOp->p3==0 || pOp->p3==1 ); + sqlite3VdbeMemSetInt64(&aMem[pOp->p2], + sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i); + break; +} + /* Opcode: Not P1 P2 * * * ** Synopsis: r[P2]= !r[P1] ** @@ -2206,16 +2270,16 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ case OP_Not: { /* same as TK_NOT, in1, out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; - sqlite3VdbeMemSetNull(pOut); if( (pIn1->flags & MEM_Null)==0 ){ - pOut->flags = MEM_Int; - pOut->u.i = !sqlite3VdbeIntValue(pIn1); + sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0)); + }else{ + sqlite3VdbeMemSetNull(pOut); } break; } /* Opcode: BitNot P1 P2 * * * -** Synopsis: r[P1]= ~r[P1] +** Synopsis: r[P2]= ~r[P1] ** ** Interpret the content of register P1 as an integer. Store the ** ones-complement of the P1 value into register P2. If P1 holds @@ -2276,30 +2340,25 @@ case OP_Once: { /* jump */ ** is considered true if it is numeric and non-zero. If the value ** in P1 is NULL then take the jump if and only if P3 is non-zero. */ +case OP_If: { /* jump, in1 */ + int c; + c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3); + VdbeBranchTaken(c!=0, 2); + if( c ) goto jump_to_p2; + break; +} + /* Opcode: IfNot P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is False. The value ** is considered false if it has a numeric value of zero. If the value ** in P1 is NULL then take the jump if and only if P3 is non-zero. */ -case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ int c; - pIn1 = &aMem[pOp->p1]; - if( pIn1->flags & MEM_Null ){ - c = pOp->p3; - }else{ -#ifdef SQLITE_OMIT_FLOATING_POINT - c = sqlite3VdbeIntValue(pIn1)!=0; -#else - c = sqlite3VdbeRealValue(pIn1)!=0.0; -#endif - if( pOp->opcode==OP_IfNot ) c = !c; - } + c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3); VdbeBranchTaken(c!=0, 2); - if( c ){ - goto jump_to_p2; - } + if( c ) goto jump_to_p2; break; } @@ -2349,6 +2408,36 @@ case OP_IfNullRow: { /* jump */ break; } +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC +/* Opcode: Offset P1 P2 P3 * * +** Synopsis: r[P3] = sqlite_offset(P1) +** +** Store in register r[P3] the byte offset into the database file that is the +** start of the payload for the record at which that cursor P1 is currently +** pointing. +** +** P2 is the column number for the argument to the sqlite_offset() function. +** This opcode does not use P2 itself, but the P2 value is used by the +** code generator. The P1, P2, and P3 operands to this opcode are the +** same as for OP_Column. +** +** This opcode is only available if SQLite is compiled with the +** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option. +*/ +case OP_Offset: { /* out3 */ + VdbeCursor *pC; /* The VDBE cursor */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + pOut = &p->aMem[pOp->p3]; + if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); + } + break; +} +#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ + /* Opcode: Column P1 P2 P3 P4 P5 ** Synopsis: r[P3]=PX ** @@ -2386,9 +2475,7 @@ case OP_Column: { const u8 *zData; /* Part of the record being decoded */ const u8 *zHdr; /* Next unparsed byte of the header */ const u8 *zEndHdr; /* Pointer to first byte after the header */ - u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset */ - u32 avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ @@ -2415,11 +2502,13 @@ case OP_Column: { if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ if( pC->eCurType==CURTYPE_PSEUDO ){ - assert( pC->uc.pseudoTableReg>0 ); - pReg = &aMem[pC->uc.pseudoTableReg]; + /* For the special case of as pseudo-cursor, the seekResult field + ** identifies the register that holds the record */ + assert( pC->seekResult>0 ); + pReg = &aMem[pC->seekResult]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); - pC->payloadSize = pC->szRow = avail = pReg->n; + pC->payloadSize = pC->szRow = pReg->n; pC->aRow = (u8*)pReg->z; }else{ sqlite3VdbeMemSetNull(pDest); @@ -2431,23 +2520,19 @@ case OP_Column: { assert( pCrsr ); assert( sqlite3BtreeCursorIsValid(pCrsr) ); pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); - pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail); - assert( avail<=65536 ); /* Maximum page size is 64KiB */ - if( pC->payloadSize <= (u32)avail ){ - pC->szRow = pC->payloadSize; - }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); + assert( pC->szRow<=pC->payloadSize ); + assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ + if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; - }else{ - pC->szRow = avail; } } pC->cacheStatus = p->cacheCtr; - pC->iHdrOffset = getVarint32(pC->aRow, offset); + pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]); pC->nHdrParsed = 0; - aOffset[0] = offset; - if( availszRowaRow does not have to hold the entire row, but it does at least ** need to cover the header of the record. If pC->aRow does not contain ** the complete header, then set it to zero, forcing the header to be @@ -2464,17 +2549,26 @@ case OP_Column: { ** 3-byte type for each of the maximum of 32768 columns plus three ** extra bytes for the header length itself. 32768*3 + 3 = 98307. */ - if( offset > 98307 || offset > pC->payloadSize ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; + if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){ + goto op_column_corrupt; } - }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/ - /* The following goto is an optimization. It can be omitted and - ** everything will still work. But OP_Column is measurably faster - ** by skipping the subsequent conditional, which is always true. + }else{ + /* This is an optimization. By skipping over the first few tests + ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a + ** measurable performance gain. + ** + ** This branch is taken even if aOffset[0]==0. Such a record is never + ** generated by SQLite, and could be considered corruption, but we + ** accept it for historical reasons. When aOffset[0]==0, the code this + ** branch jumps to reads past the end of the record, but never more + ** than a few bytes. Even if the record occurs at the end of the page + ** content area, the "page header" comes after the page content and so + ** this overread is harmless. Similar overreads can occur for a corrupt + ** database file. */ zData = pC->aRow; assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ + testcase( aOffset[0]==0 ); goto op_column_read_header; } } @@ -2503,6 +2597,7 @@ case OP_Column: { offset64 = aOffset[i]; zHdr = zData + pC->iHdrOffset; zEndHdr = zData + aOffset[0]; + testcase( zHdr>=zEndHdr ); do{ if( (t = zHdr[0])<0x80 ){ zHdr++; @@ -2523,9 +2618,13 @@ case OP_Column: { if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) || (offset64 > pC->payloadSize) ){ - if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; + if( aOffset[0]==0 ){ + i = 0; + zHdr = zEndHdr; + }else{ + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + goto op_column_corrupt; + } } pC->nHdrParsed = i; @@ -2619,6 +2718,15 @@ op_column_out: UPDATE_MAX_BLOBSIZE(pDest); REGISTER_TRACE(pOp->p3, pDest); break; + +op_column_corrupt: + if( aOp[0].p3>0 ){ + pOp = &aOp[aOp[0].p3-1]; + break; + }else{ + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } } /* Opcode: Affinity P1 P2 * P4 * @@ -2743,9 +2851,18 @@ case OP_MakeRecord: { pRec = pLast; do{ assert( memIsValid(pRec) ); - pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); + serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); if( pRec->flags & MEM_Zero ){ - if( nData ){ + if( serial_type==0 ){ + /* Values with MEM_Null and MEM_Zero are created by xColumn virtual + ** table methods that never invoke sqlite3_result_xxxxx() while + ** computing an unchanging column value in an UPDATE statement. + ** Give such values a special internal-use-only serial-type of 10 + ** so that they can be passed through to xUpdate and have + ** a true sqlite3_value_nochange(). */ + assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB ); + serial_type = 10; + }else if( nData ){ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; }else{ nZero += pRec->u.nZero; @@ -2756,6 +2873,7 @@ case OP_MakeRecord: { testcase( serial_type==127 ); testcase( serial_type==128 ); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); + pRec->uTemp = serial_type; if( pRec==pData0 ) break; pRec--; }while(1); @@ -2776,17 +2894,25 @@ case OP_MakeRecord: { if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } /* Make sure the output register has a buffer large enough to store ** the new record. The output register (pOp->p3) is not allowed to ** be one of the input registers (because the following call to ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). */ - if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ - goto no_mem; + if( nByte+nZero<=pOut->szMalloc ){ + /* The output register is already large enough to hold the record. + ** No error checks or buffer enlargement is required */ + pOut->z = pOut->zMalloc; + }else{ + /* Need to make sure that the output is not too big and then enlarge + ** the output register to hold the full result */ + if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ + goto no_mem; + } } zNewRecord = (u8 *)pOut->z; @@ -2976,7 +3102,7 @@ case OP_Savepoint: { } } if( isSchemaChange ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); sqlite3ResetAllSchemasOfConnection(db); db->mDbFlags |= DBFLAG_SchemaChange; } @@ -3118,8 +3244,7 @@ case OP_AutoCommit: { */ case OP_Transaction: { Btree *pBt; - int iMeta; - int iGen; + int iMeta = 0; assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); @@ -3132,7 +3257,7 @@ case OP_Transaction: { pBt = db->aDb[pOp->p1].pBt; if( pBt ){ - rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); testcase( rc==SQLITE_BUSY_SNAPSHOT ); testcase( rc==SQLITE_BUSY_RECOVERY ); if( rc!=SQLITE_OK ){ @@ -3165,19 +3290,17 @@ case OP_Transaction: { p->nStmtDefCons = db->nDeferredCons; p->nStmtDefImmCons = db->nDeferredImmCons; } - - /* Gather the schema version number for checking: + } + assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); + if( pOp->p5 + && (iMeta!=pOp->p3 + || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) + ){ + /* ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema ** version is checked to ensure that the schema has not changed since the ** SQL statement was prepared. */ - sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); - iGen = db->aDb[pOp->p1].pSchema->iGeneration; - }else{ - iGen = iMeta = 0; - } - assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); - if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie @@ -3246,6 +3369,8 @@ case OP_ReadCookie: { /* out2 */ */ case OP_SetCookie: { Db *pDb; + + sqlite3VdbeIncrWriteCounter(p, 0); assert( pOp->p2p1>=0 && pOp->p1nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); @@ -3266,7 +3391,7 @@ case OP_SetCookie: { if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database ** schema is changed. Ticket #1644 */ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); p->expired = 0; } if( rc ) goto abort_due_to_error; @@ -3284,59 +3409,78 @@ case OP_SetCookie: { ** values need not be contiguous but all P1 values should be small integers. ** It is an error for P1 to be negative. ** -** If P5!=0 then use the content of register P2 as the root page, not -** the value of P2 itself. -** -** There will be a read lock on the database whenever there is an -** open cursor. If the database was unlocked prior to this instruction -** then a read lock is acquired as part of this instruction. A read -** lock allows other processes to read the database but prohibits -** any other process from modifying the database. The read lock is -** released when all cursors are closed. If this instruction attempts -** to get a read lock but fails, the script terminates with an -** SQLITE_BUSY error code. +** Allowed P5 bits: +**
        +**
      • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
      ** ** The P4 value may be either an integer (P4_INT32) or a pointer to ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table. +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. ** ** See also: OpenWrite, ReopenIdx */ /* Opcode: ReopenIdx P1 P2 P3 P4 P5 ** Synopsis: root=P2 iDb=P3 ** -** The ReopenIdx opcode works exactly like ReadOpen except that it first -** checks to see if the cursor on P1 is already open with a root page -** number of P2 and if it is this opcode becomes a no-op. In other words, +** The ReopenIdx opcode works like OP_OpenRead except that it first +** checks to see if the cursor on P1 is already open on the same +** b-tree and if it is this opcode becomes a no-op. In other words, ** if the cursor is already open, do not reopen it. ** -** The ReopenIdx opcode may only be used with P5==0 and with P4 being -** a P4_KEYINFO object. Furthermore, the P3 value must be the same as -** every other ReopenIdx or OpenRead for the same cursor number. +** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ +** and with P4 being a P4_KEYINFO object. Furthermore, the P3 value must +** be the same as every other ReopenIdx or OpenRead for the same cursor +** number. ** -** See the OpenRead opcode documentation for additional information. +** Allowed P5 bits: +**
        +**
      • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
      +** +** See also: OP_OpenRead, OP_OpenWrite */ /* Opcode: OpenWrite P1 P2 P3 P4 P5 ** Synopsis: root=P2 iDb=P3 ** ** Open a read/write cursor named P1 on the table or index whose root -** page is P2. Or if P5!=0 use the content of register P2 to find the -** root page. +** page is P2 (or whose root page is held in register P2 if the +** OPFLAG_P2ISREG bit is set in P5 - see below). ** ** The P4 value may be either an integer (P4_INT32) or a pointer to ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table, or to the -** largest index of any column of the table that is actually used. +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. ** -** This instruction works just like OpenRead except that it opens the cursor -** in read/write mode. For a given table, there can be one or more read-only -** cursors or a single read/write cursor but not both. +** Allowed P5 bits: +**
        +**
      • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
      • 0x08 OPFLAG_FORDELETE: This cursor is used only to seek +** and subsequently delete entries in an index btree. This is a +** hint to the storage engine that the storage engine is allowed to +** ignore. The hint is not used by the official SQLite b*tree storage +** engine, but is used by COMDB2. +**
      • 0x10 OPFLAG_P2ISREG: Use the content of register P2 +** as the root page, not the value of P2 itself. +**
      ** -** See also OpenRead. +** This instruction works like OpenRead except that it opens the cursor +** in read/write mode. +** +** See also: OP_OpenRead, OP_ReopenIdx */ case OP_ReopenIdx: { int nField; @@ -3365,7 +3509,7 @@ case OP_OpenWrite: assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx || p->readOnly==0 ); - if( p->expired ){ + if( p->expired==1 ){ rc = SQLITE_ABORT_ROLLBACK; goto abort_due_to_error; } @@ -3392,12 +3536,13 @@ case OP_OpenWrite: if( pOp->p5 & OPFLAG_P2ISREG ){ assert( p2>0 ); assert( p2<=(p->nMem+1 - p->nCursor) ); + assert( pOp->opcode==OP_OpenWrite ); pIn2 = &aMem[p2]; assert( memIsValid(pIn2) ); assert( (pIn2->flags & MEM_Int)!=0 ); sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; - /* The p2 value always comes from a prior OP_CreateTable opcode and + /* The p2 value always comes from a prior OP_CreateBtree opcode and ** that opcode will always set the p2 value to 2 or more or else fail. ** If there were a failure, the prepared statement would have halted ** before reaching this instruction. */ @@ -3520,7 +3665,7 @@ case OP_OpenEphemeral: { rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1); + rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling @@ -3618,8 +3763,13 @@ case OP_OpenPseudo: { pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; - pCx->uc.pseudoTableReg = pOp->p2; + pCx->seekResult = pOp->p2; pCx->isTable = 1; + /* Give this pseudo-cursor a fake BtCursor pointer so that pCx + ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test + ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto() + ** which is a performance optimization */ + pCx->uc.pCursor = sqlite3BtreeFakeValidCursor(); assert( pOp->p5==0 ); break; } @@ -3742,10 +3892,10 @@ case OP_ColumnsUsed: { ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ -case OP_SeekLT: /* jump, in3 */ -case OP_SeekLE: /* jump, in3 */ -case OP_SeekGE: /* jump, in3 */ -case OP_SeekGT: { /* jump, in3 */ +case OP_SeekLT: /* jump, in3, group */ +case OP_SeekLE: /* jump, in3, group */ +case OP_SeekGE: /* jump, in3, group */ +case OP_SeekGT: { /* jump, in3, group */ int res; /* Comparison result */ int oc; /* Opcode */ VdbeCursor *pC; /* The cursor to seek */ @@ -3923,6 +4073,25 @@ seek_not_found: break; } +/* Opcode: SeekHit P1 P2 * * * +** Synopsis: seekHit=P2 +** +** Set the seekHit flag on cursor P1 to the value in P2. +** The seekHit flag is used by the IfNoHope opcode. +** +** P1 must be a valid b-tree cursor. P2 must be a boolean value, +** either 0 or 1. +*/ +case OP_SeekHit: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pOp->p2==0 || pOp->p2==1 ); + pC->seekHit = pOp->p2 & 1; + break; +} + /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** @@ -3957,7 +4126,34 @@ seek_not_found: ** advanced in either direction. In other words, the Next and Prev ** opcodes do not work after this operation. ** -** See also: Found, NotExists, NoConflict +** See also: Found, NotExists, NoConflict, IfNoHope +*/ +/* Opcode: IfNoHope P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** Register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then +** this opcode is a no-op. But if the seekHit flag of P1 is clear, then +** check to see if there is any entry in P1 that matches the +** prefix identified by P3 and P4. If no entry matches the prefix, +** jump to P2. Otherwise fall through. +** +** This opcode behaves like OP_NotFound if the seekHit +** flag is clear and it behaves like OP_Noop if the seekHit flag is set. +** +** This opcode is used in IN clause processing for a multi-column key. +** If an IN clause is attached to an element of the key other than the +** left-most element, and if there are no matches on the most recent +** seek over the whole key, then it might be that one of the key element +** to the left is prohibiting a match, and hence there is "no hope" of +** any match regardless of how many IN clause elements are checked. +** In such a case, we abandon the IN clause search early, using this +** opcode. The opcode name comes from the fact that the +** jump is taken if there is "no hope" of achieving a match. +** +** See also: NotFound, SeekHit */ /* Opcode: NoConflict P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] @@ -3982,6 +4178,14 @@ seek_not_found: ** ** See also: NotFound, Found, NotExists */ +case OP_IfNoHope: { /* jump, in3 */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( pC->seekHit ) break; + /* Fall through into OP_NotFound */ +} case OP_NoConflict: /* jump, in3 */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ @@ -4119,18 +4323,26 @@ case OP_SeekRowid: { /* jump, in3 */ pIn3 = &aMem[pOp->p3]; if( (pIn3->flags & MEM_Int)==0 ){ + /* Make sure pIn3->u.i contains a valid integer representation of + ** the key value, but do not change the datatype of the register, as + ** other parts of the perpared statement might be depending on the + ** current datatype. */ + u16 origFlags = pIn3->flags; + int isNotInt; applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding); - if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2; + isNotInt = (pIn3->flags & MEM_Int)==0; + pIn3->flags = origFlags; + if( isNotInt ) goto jump_to_p2; } /* Fall through into OP_NotExists */ case OP_NotExists: /* jump, in3 */ pIn3 = &aMem[pOp->p3]; - assert( pIn3->flags & MEM_Int ); + assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); #ifdef SQLITE_DEBUG - pC->seekOp = 0; + pC->seekOp = OP_SeekRowid; #endif assert( pC->isTable ); assert( pC->eCurType==CURTYPE_BTREE ); @@ -4205,6 +4417,7 @@ case OP_NewRowid: { /* out2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); + assert( pC->isTable ); assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); { @@ -4361,10 +4574,8 @@ case OP_InsertInt: { int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ Table *pTab; /* Table structure - used by update and pre-update hooks */ - int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ BtreePayload x; /* Payload to be inserted */ - op = 0; pData = &aMem[pOp->p2]; assert( pOp->p1>=0 && pOp->p1nCursor ); assert( memIsValid(pData) ); @@ -4375,6 +4586,7 @@ case OP_InsertInt: { assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable ); assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); REGISTER_TRACE(pOp->p2, pData); + sqlite3VdbeIncrWriteCounter(p, pC); if( pOp->opcode==OP_Insert ){ pKey = &aMem[pOp->p3]; @@ -4392,33 +4604,30 @@ case OP_InsertInt: { zDb = db->aDb[pC->iDb].zDbSName; pTab = pOp->p4.pTab; assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) ); - op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); }else{ - pTab = 0; /* Not needed. Silence a compiler warning. */ + pTab = 0; zDb = 0; /* Not needed. Silence a compiler warning. */ } #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* Invoke the pre-update hook, if any */ - if( db->xPreUpdateCallback - && pOp->p4type==P4_TABLE - && !(pOp->p5 & OPFLAG_ISUPDATE) - ){ - sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2); + if( pTab ){ + if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){ + sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2); + } + if( db->xUpdateCallback==0 || pTab->aCol==0 ){ + /* Prevent post-update hook from running in cases when it should not */ + pTab = 0; + } } if( pOp->p5 & OPFLAG_ISNOOP ) break; #endif if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; - if( pData->flags & MEM_Null ){ - x.pData = 0; - x.nData = 0; - }else{ - assert( pData->flags & (MEM_Blob|MEM_Str) ); - x.pData = pData->z; - x.nData = pData->n; - } + assert( pData->flags & (MEM_Blob|MEM_Str) ); + x.pData = pData->z; + x.nData = pData->n; seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); if( pData->flags & MEM_Zero ){ x.nZero = pData->u.nZero; @@ -4434,8 +4643,12 @@ case OP_InsertInt: { /* Invoke the update-hook if required. */ if( rc ) goto abort_due_to_error; - if( db->xUpdateCallback && op ){ - db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey); + if( pTab ){ + assert( db->xUpdateCallback!=0 ); + assert( pTab->aCol!=0 ); + db->xUpdateCallback(db->pUpdateArg, + (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT, + zDb, pTab->zName, x.nKey); } break; } @@ -4488,6 +4701,7 @@ case OP_Delete: { assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); assert( pC->deferredMoveto==0 ); + sqlite3VdbeIncrWriteCounter(p, pC); #ifdef SQLITE_DEBUG if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){ @@ -4656,10 +4870,10 @@ case OP_SorterData: { ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. ** -** If P3!=0 then this opcode is allowed to make an ephermeral pointer +** If P3!=0 then this opcode is allowed to make an ephemeral pointer ** into the database page. That means that the content of the output ** register will be invalidated as soon as the cursor moves - including -** moves caused by other cursors that "save" the the current cursors +** moves caused by other cursors that "save" the current cursors ** position in order that they can write to the same table. If P3==0 ** then a copy of the data is made into memory. P3!=0 is faster, but ** P3==0 is safer. @@ -4782,6 +4996,9 @@ case OP_NullRow: { assert( pC->uc.pCursor!=0 ); sqlite3BtreeClearCursor(pC->uc.pCursor); } +#ifdef SQLITE_DEBUG + if( pC->seekOp==0 ) pC->seekOp = OP_NullRow; +#endif break; } @@ -4900,7 +5117,7 @@ case OP_Sort: { /* jump */ p->aCounter[SQLITE_STMTSTATUS_SORT]++; /* Fall through into OP_Rewind */ } -/* Opcode: Rewind P1 P2 * * * +/* Opcode: Rewind P1 P2 * * P5 ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. @@ -4908,6 +5125,10 @@ case OP_Sort: { /* jump */ ** If the table or index is not empty, fall through to the following ** instruction. ** +** If P5 is non-zero and the table is not empty, then the "skip-next" +** flag is set on the cursor so that the next OP_Next instruction +** executed on it is a no-op. +** ** This opcode leaves the cursor configured to move in forward order, ** from the beginning toward the end. In other words, the cursor is ** configured to use Next, not Prev. @@ -4932,6 +5153,9 @@ case OP_Rewind: { /* jump */ pCrsr = pC->uc.pCursor; assert( pCrsr ); rc = sqlite3BtreeFirst(pCrsr, &res); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr); +#endif pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } @@ -4968,12 +5192,7 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. ** -** See also: Prev, NextIfOpen -*/ -/* Opcode: NextIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Next except that if cursor P1 is not -** open it behaves a no-op. +** See also: Prev */ /* Opcode: Prev P1 P2 P3 P4 P5 ** @@ -5001,11 +5220,6 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ -/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Prev except that if cursor P1 is not -** open it behaves a no-op. -*/ /* Opcode: SorterNext P1 P2 * * P5 ** ** This opcode works just like OP_Next except that P1 must be a @@ -5020,10 +5234,6 @@ case OP_SorterNext: { /* jump */ assert( isSorter(pC) ); rc = sqlite3VdbeSorterNext(db, pC); goto next_tail; -case OP_PrevIfOpen: /* jump */ -case OP_NextIfOpen: /* jump */ - if( p->apCsr[pOp->p1]==0 ) break; - /* Fall through */ case OP_Prev: /* jump */ case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -5034,17 +5244,17 @@ case OP_Next: /* jump */ assert( pC->eCurType==CURTYPE_BTREE ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); - assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); - assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); - /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. + /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ - assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen + assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE - || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); - assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found + || pC->seekOp==OP_NullRow); + assert( pOp->opcode!=OP_Prev || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE - || pC->seekOp==OP_Last ); + || pC->seekOp==OP_Last + || pC->seekOp==OP_NullRow); rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); next_tail: @@ -5106,6 +5316,7 @@ case OP_IdxInsert: { /* in2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; + sqlite3VdbeIncrWriteCounter(p, pC); assert( pC!=0 ); assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); pIn2 = &aMem[pOp->p2]; @@ -5152,6 +5363,7 @@ case OP_IdxDelete: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3VdbeIncrWriteCounter(p, pC); pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); assert( pOp->p5==0 ); @@ -5325,7 +5537,13 @@ case OP_IdxGE: { /* jump */ } r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG - { int i; for(i=0; ip3+i, &aMem[pOp->p3+i]); + } + } #endif res = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); @@ -5374,6 +5592,7 @@ case OP_Destroy: { /* out2 */ int iMoved; int iDb; + sqlite3VdbeIncrWriteCounter(p, 0); assert( p->readOnly==0 ); assert( pOp->p1>1 ); pOut = out2Prerelease(p, pOp); @@ -5423,6 +5642,7 @@ case OP_Destroy: { /* out2 */ case OP_Clear: { int nChange; + sqlite3VdbeIncrWriteCounter(p, 0); nChange = 0; assert( p->readOnly==0 ); assert( DbMaskTest(p->btreeMask, pOp->p2) ); @@ -5466,50 +5686,29 @@ case OP_ResetSorter: { break; } -/* Opcode: CreateTable P1 P2 * * * -** Synopsis: r[P2]=root iDb=P1 +/* Opcode: CreateBtree P1 P2 P3 * * +** Synopsis: r[P2]=root iDb=P1 flags=P3 ** -** Allocate a new table in the main database file if P1==0 or in the -** auxiliary database file if P1==1 or in an attached database if -** P1>1. Write the root page number of the new table into -** register P2 -** -** The difference between a table and an index is this: A table must -** have a 4-byte integer key and can have arbitrary data. An index -** has an arbitrary key but no data. -** -** See also: CreateIndex +** Allocate a new b-tree in the main database file if P1==0 or in the +** TEMP database file if P1==1 or in an attached database if +** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table +** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table. +** The root page number of the new b-tree is stored in register P2. */ -/* Opcode: CreateIndex P1 P2 * * * -** Synopsis: r[P2]=root iDb=P1 -** -** Allocate a new index in the main database file if P1==0 or in the -** auxiliary database file if P1==1 or in an attached database if -** P1>1. Write the root page number of the new table into -** register P2. -** -** See documentation on OP_CreateTable for additional information. -*/ -case OP_CreateIndex: /* out2 */ -case OP_CreateTable: { /* out2 */ +case OP_CreateBtree: { /* out2 */ int pgno; - int flags; Db *pDb; + sqlite3VdbeIncrWriteCounter(p, 0); pOut = out2Prerelease(p, pOp); pgno = 0; + assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY ); assert( pOp->p1>=0 && pOp->p1nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); assert( p->readOnly==0 ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); - if( pOp->opcode==OP_CreateTable ){ - /* flags = BTREE_INTKEY; */ - flags = BTREE_INTKEY; - }else{ - flags = BTREE_BLOBKEY; - } - rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); + rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3); if( rc ) goto abort_due_to_error; pOut->u.i = pgno; break; @@ -5520,6 +5719,7 @@ case OP_CreateTable: { /* out2 */ ** Run the SQL statement or statements specified in the P4 string. */ case OP_SqlExec: { + sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); db->nSqlExec--; @@ -5530,7 +5730,8 @@ case OP_SqlExec: { /* Opcode: ParseSchema P1 * * P4 * ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 -** that match the WHERE clause P4. +** that match the WHERE clause P4. If P4 is a NULL pointer, then the +** entire schema for P1 is reparsed. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. @@ -5554,11 +5755,22 @@ case OP_ParseSchema: { iDb = pOp->p1; assert( iDb>=0 && iDbnDb ); assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); - /* Used to be a conditional */ { + +#ifndef SQLITE_OMIT_ALTERTABLE + if( pOp->p4.z==0 ){ + sqlite3SchemaClear(db->aDb[iDb].pSchema); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); + db->mDbFlags |= DBFLAG_SchemaChange; + p->expired = 0; + }else +#endif + { zMaster = MASTER_NAME; initData.db = db; - initData.iDb = pOp->p1; + initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; + initData.mInitFlags = 0; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); @@ -5609,6 +5821,7 @@ case OP_LoadAnalysis: { ** schema consistent with what is on disk. */ case OP_DropTable: { + sqlite3VdbeIncrWriteCounter(p, 0); sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); break; } @@ -5622,6 +5835,7 @@ case OP_DropTable: { ** schema consistent with what is on disk. */ case OP_DropIndex: { + sqlite3VdbeIncrWriteCounter(p, 0); sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); break; } @@ -5635,6 +5849,7 @@ case OP_DropIndex: { ** schema consistent with what is on disk. */ case OP_DropTrigger: { + sqlite3VdbeIncrWriteCounter(p, 0); sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); break; } @@ -5671,7 +5886,7 @@ case OP_IntegrityCk: { nRoot = pOp->p2; aRoot = pOp->p4.ai; assert( nRoot>0 ); - assert( aRoot[nRoot]==0 ); + assert( aRoot[0]==nRoot ); assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pnErr = &aMem[pOp->p3]; assert( (pnErr->flags & MEM_Int)!=0 ); @@ -5679,7 +5894,7 @@ case OP_IntegrityCk: { pIn1 = &aMem[pOp->p1]; assert( pOp->p5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); - z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, + z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, (int)pnErr->u.i+1, &nErr); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ @@ -5708,11 +5923,11 @@ case OP_RowSetAdd: { /* in1, in2 */ pIn1 = &aMem[pOp->p1]; pIn2 = &aMem[pOp->p2]; assert( (pIn2->flags & MEM_Int)!=0 ); - if( (pIn1->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(pIn1); - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; } - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i); + assert( sqlite3VdbeMemIsRowSet(pIn1) ); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); break; } @@ -5728,8 +5943,9 @@ case OP_RowSetRead: { /* jump, in1, out3 */ i64 val; pIn1 = &aMem[pOp->p1]; - if( (pIn1->flags & MEM_RowSet)==0 - || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 + assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); + if( (pIn1->flags & MEM_Blob)==0 + || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 ){ /* The boolean index is empty */ sqlite3VdbeMemSetNull(pIn1); @@ -5778,20 +5994,19 @@ case OP_RowSetTest: { /* jump, in1, in3 */ /* If there is anything other than a rowset object in memory cell P1, ** delete it now and initialize P1 with an empty rowset */ - if( (pIn1->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(pIn1); - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; } - + assert( sqlite3VdbeMemIsRowSet(pIn1) ); assert( pOp->p4type==P4_INT32 ); assert( iSet==-1 || iSet>=0 ); if( iSet ){ - exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); + exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); VdbeBranchTaken(exists!=0,2); if( exists ) goto jump_to_p2; } if( iSet>=0 ){ - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); } break; } @@ -5855,7 +6070,7 @@ case OP_Program: { /* jump */ ** of the current program, and the memory required at runtime to execute ** the trigger program. If this trigger has been fired before, then pRt ** is already allocated. Otherwise, it must be initialized. */ - if( (pRt->flags&MEM_Frame)==0 ){ + if( (pRt->flags&MEM_Blob)==0 ){ /* SubProgram.nMem is set to the number of memory cells used by the ** program stored in SubProgram.aOp. As well as these, one memory ** cell is required for each cursor used by the program. Set local @@ -5873,8 +6088,10 @@ case OP_Program: { /* jump */ goto no_mem; } sqlite3VdbeMemRelease(pRt); - pRt->flags = MEM_Frame; - pRt->u.pFrame = pFrame; + pRt->flags = MEM_Blob|MEM_Dyn; + pRt->z = (char*)pFrame; + pRt->n = nByte; + pRt->xDel = sqlite3VdbeFrameMemDel; pFrame->v = p; pFrame->nChildMem = nMem; @@ -5890,6 +6107,9 @@ case OP_Program: { /* jump */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS pFrame->anExec = p->anExec; #endif +#ifdef SQLITE_DEBUG + pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; +#endif pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ @@ -5897,7 +6117,8 @@ case OP_Program: { /* jump */ pMem->db = db; } }else{ - pFrame = pRt->u.pFrame; + pFrame = (VdbeFrame*)pRt->z; + assert( pRt->xDel==sqlite3VdbeFrameMemDel ); assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); assert( pProgram->nCsr==pFrame->nChildCsr ); @@ -6126,24 +6347,35 @@ case OP_DecrJumpZero: { /* jump, in1 */ } -/* Opcode: AggStep0 * P2 P3 P4 P5 +/* Opcode: AggStep * P2 P3 P4 P5 ** Synopsis: accum=r[P3] step(r[P2@P5]) ** -** Execute the step function for an aggregate. The -** function has P5 arguments. P4 is a pointer to the FuncDef -** structure that specifies the function. Register P3 is the +** Execute the xStep function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the ** accumulator. ** ** The P5 arguments are taken from register P2 and its ** successors. */ -/* Opcode: AggStep * P2 P3 P4 P5 +/* Opcode: AggInverse * P2 P3 P4 P5 +** Synopsis: accum=r[P3] inverse(r[P2@P5]) +** +** Execute the xInverse function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +*/ +/* Opcode: AggStep1 P1 P2 P3 P4 P5 ** Synopsis: accum=r[P3] step(r[P2@P5]) ** -** Execute the step function for an aggregate. The -** function has P5 arguments. P4 is a pointer to an sqlite3_context -** object that is used to run the function. Register P3 is -** as the accumulator. +** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an +** aggregate. The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. ** ** The P5 arguments are taken from register P2 and its ** successors. @@ -6154,7 +6386,8 @@ case OP_DecrJumpZero: { /* jump, in1 */ ** sqlite3_context only happens once, instead of on each call to the ** step function. */ -case OP_AggStep0: { +case OP_AggInverse: +case OP_AggStep: { int n; sqlite3_context *pCtx; @@ -6163,28 +6396,47 @@ case OP_AggStep0: { assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); + pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + + (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); if( pCtx==0 ) goto no_mem; pCtx->pMem = 0; + pCtx->pOut = (Mem*)&(pCtx->argv[n]); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; + pCtx->skipFlag = 0; + pCtx->isError = 0; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; pOp->p4.pCtx = pCtx; - pOp->opcode = OP_AggStep; + + /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */ + assert( pOp->p1==(pOp->opcode==OP_AggInverse) ); + + pOp->opcode = OP_AggStep1; /* Fall through into OP_AggStep */ } -case OP_AggStep: { +case OP_AggStep1: { int i; sqlite3_context *pCtx; Mem *pMem; - Mem t; assert( pOp->p4type==P4_FUNCCTX ); pCtx = pOp->p4.pCtx; pMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + if( pOp->p1 ){ + /* This is an OP_AggInverse call. Verify that xStep has always + ** been called at least once prior to any xInverse call. */ + assert( pMem->uTemp==0x1122e0e3 ); + }else{ + /* This is an OP_AggStep call. Mark it as such. */ + pMem->uTemp = 0x1122e0e3; + } +#endif + /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it @@ -6202,48 +6454,80 @@ case OP_AggStep: { #endif pMem->n++; - sqlite3VdbeMemInit(&t, db, MEM_Null); - pCtx->pOut = &t; - pCtx->fErrorOrAux = 0; - pCtx->skipFlag = 0; + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->isError==0 ); + assert( pCtx->skipFlag==0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p1 ){ + (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv); + }else +#endif (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ - if( pCtx->fErrorOrAux ){ - if( pCtx->isError ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(&t)); + + if( pCtx->isError ){ + if( pCtx->isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); rc = pCtx->isError; } - sqlite3VdbeMemRelease(&t); + if( pCtx->skipFlag ){ + assert( pOp[-1].opcode==OP_CollSeq ); + i = pOp[-1].p1; + if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); + pCtx->skipFlag = 0; + } + sqlite3VdbeMemRelease(pCtx->pOut); + pCtx->pOut->flags = MEM_Null; + pCtx->isError = 0; if( rc ) goto abort_due_to_error; - }else{ - assert( t.flags==MEM_Null ); - } - if( pCtx->skipFlag ){ - assert( pOp[-1].opcode==OP_CollSeq ); - i = pOp[-1].p1; - if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); } + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->skipFlag==0 ); break; } /* Opcode: AggFinal P1 P2 * P4 * ** Synopsis: accum=r[P1] N=P2 ** -** Execute the finalizer function for an aggregate. P1 is -** the memory location that is the accumulator for the aggregate. +** P1 is the memory location that is the accumulator for an aggregate +** or window function. Execute the finalizer function +** for an aggregate and store the result in P1. ** ** P2 is the number of arguments that the step function takes and ** P4 is a pointer to the FuncDef for this function. The P2 ** argument is not used by this opcode. It is only there to disambiguate ** functions that can take varying numbers of arguments. The -** P4 argument is only needed for the degenerate case where +** P4 argument is only needed for the case where ** the step function was not previously called. */ +/* Opcode: AggValue * P2 P3 P4 * +** Synopsis: r[P3]=value N=P2 +** +** Invoke the xValue() function and store the result in register P3. +** +** P2 is the number of arguments that the step function takes and +** P4 is a pointer to the FuncDef for this function. The P2 +** argument is not used by this opcode. It is only there to disambiguate +** functions that can take varying numbers of arguments. The +** P4 argument is only needed for the case where +** the step function was not previously called. +*/ +case OP_AggValue: case OP_AggFinal: { Mem *pMem; assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( pOp->p3==0 || pOp->opcode==OP_AggValue ); pMem = &aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); - rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p3 ){ + rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc); + pMem = &aMem[pOp->p3]; + }else +#endif + { + rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); + } + if( rc ){ sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); goto abort_due_to_error; @@ -6438,7 +6722,7 @@ case OP_IncrVacuum: { /* jump */ } #endif -/* Opcode: Expire P1 * * * * +/* Opcode: Expire P1 P2 * * * ** ** Cause precompiled statements to expire. When an expired statement ** is executed using sqlite3_step() it will either automatically @@ -6447,12 +6731,19 @@ case OP_IncrVacuum: { /* jump */ ** ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, ** then only the currently executing statement is expired. +** +** If P2 is 0, then SQL statements are expired immediately. If P2 is 1, +** then running SQL statements are allowed to continue to run to completion. +** The P2==1 case occurs when a CREATE INDEX or similar schema change happens +** that might help the statement run faster but which does not affect the +** correctness of operation. */ case OP_Expire: { + assert( pOp->p2==0 || pOp->p2==1 ); if( !pOp->p1 ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, pOp->p2); }else{ - p->expired = 1; + p->expired = pOp->p2+1; } break; } @@ -6666,12 +6957,19 @@ case OP_VFilter: { /* jump */ #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VColumn P1 P2 P3 * * +/* Opcode: VColumn P1 P2 P3 * P5 ** Synopsis: r[P3]=vcolumn(P2) ** -** Store the value of the P2-th column of -** the row of the virtual-table that the -** P1 cursor is pointing to into register P3. +** Store in register P3 the value of the P2-th column of +** the current row of the virtual-table of cursor P1. +** +** If the VColumn opcode is being used to fetch the value of +** an unchanging column during an UPDATE operation, then the P5 +** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange() +** function to return true inside the xColumn method of the virtual +** table implementation. The P5 column might also contain other +** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are +** unused by OP_VColumn. */ case OP_VColumn: { sqlite3_vtab *pVtab; @@ -6693,10 +6991,18 @@ case OP_VColumn: { assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; - MemSetTypeFlag(pDest, MEM_Null); + testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 ); + if( pOp->p5 & OPFLAG_NOCHNG ){ + sqlite3VdbeMemSetNull(pDest); + pDest->flags = MEM_Null|MEM_Zero; + pDest->u.nZero = 0; + }else{ + MemSetTypeFlag(pDest, MEM_Null); + } rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); sqlite3VtabImportErrmsg(p, pVtab); - if( sContext.isError ){ + if( sContext.isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest)); rc = sContext.isError; } sqlite3VdbeChangeEncoding(pDest, encoding); @@ -6763,7 +7069,10 @@ case OP_VNext: { /* jump */ case OP_VRename: { sqlite3_vtab *pVtab; Mem *pName; - + int isLegacy; + + isLegacy = (db->flags & SQLITE_LegacyAlter); + db->flags |= SQLITE_LegacyAlter; pVtab = pOp->p4.pVtab->pVtab; pName = &aMem[pOp->p1]; assert( pVtab->pModule->xRename ); @@ -6777,6 +7086,7 @@ case OP_VRename: { rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); if( rc ) goto abort_due_to_error; rc = pVtab->pModule->xRename(pVtab, pName->z); + if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter; sqlite3VtabImportErrmsg(p, pVtab); p->expired = 0; if( rc ) goto abort_due_to_error; @@ -6825,6 +7135,8 @@ case OP_VUpdate: { || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace ); assert( p->readOnly==0 ); + if( db->mallocFailed ) goto no_mem; + sqlite3VdbeIncrWriteCounter(p, 0); pVtab = pOp->p4.pVtab->pVtab; if( pVtab==0 || NEVER(pVtab->pModule==0) ){ rc = SQLITE_LOCKED; @@ -6945,8 +7257,8 @@ case OP_MaxPgcnt: { /* out2 */ ** ** See also: Function0, AggStep, AggFinal */ -case OP_PureFunc0: -case OP_Function0: { +case OP_PureFunc0: /* group */ +case OP_Function0: { /* group */ int n; sqlite3_context *pCtx; @@ -6961,6 +7273,7 @@ case OP_Function0: { pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; + pCtx->isError = 0; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; pOp->p4.pCtx = pCtx; @@ -6969,8 +7282,8 @@ case OP_Function0: { pOp->opcode += 2; /* Fall through into OP_Function */ } -case OP_PureFunc: -case OP_Function: { +case OP_PureFunc: /* group */ +case OP_Function: { /* group */ int i; sqlite3_context *pCtx; @@ -6995,16 +7308,17 @@ case OP_Function: { } #endif MemSetTypeFlag(pOut, MEM_Null); - pCtx->fErrorOrAux = 0; + assert( pCtx->isError==0 ); (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ /* If the function returned an error, throw an exception */ - if( pCtx->fErrorOrAux ){ - if( pCtx->isError ){ + if( pCtx->isError ){ + if( pCtx->isError>0 ){ sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); rc = pCtx->isError; } sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); + pCtx->isError = 0; if( rc ) goto abort_due_to_error; } @@ -7019,8 +7333,14 @@ case OP_Function: { break; } - -/* Opcode: Init P1 P2 * P4 * +/* Opcode: Trace P1 P2 * P4 * +** +** Write P4 on the statement trace output if statement tracing is +** enabled. +** +** Operand P1 must be 0x7fffffff and P2 must positive. +*/ +/* Opcode: Init P1 P2 P3 P4 * ** Synopsis: Start at P2 ** ** Programs contain a single instance of this opcode as the very first @@ -7034,10 +7354,16 @@ case OP_Function: { ** ** Increment the value of P1 so that OP_Once opcodes will jump the ** first time they are evaluated for this run. +** +** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT +** error is encountered. */ +case OP_Trace: case OP_Init: { /* jump */ - char *zTrace; int i; +#ifndef SQLITE_OMIT_TRACE + char *zTrace; +#endif /* If the P4 argument is not NULL, then it must be an SQL comment string. ** The "--" string is broken up to prevent false-positives with srcck1.c. @@ -7049,7 +7375,9 @@ case OP_Init: { /* jump */ ** sqlite3_expanded_sql(P) otherwise. */ assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); - assert( pOp==p->aOp ); /* Always instruction 0 */ + + /* OP_Init is always instruction 0 */ + assert( pOp==p->aOp || pOp->opcode==OP_Trace ); #ifndef SQLITE_OMIT_TRACE if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 @@ -7092,6 +7420,7 @@ case OP_Init: { /* jump */ #endif /* SQLITE_OMIT_TRACE */ assert( pOp->p2>0 ); if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){ + if( pOp->opcode==OP_Trace ) break; for(i=1; inOp; i++){ if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0; } @@ -7125,6 +7454,22 @@ case OP_CursorHint: { } #endif /* SQLITE_ENABLE_CURSOR_HINTS */ +#ifdef SQLITE_DEBUG +/* Opcode: Abortable * * * * * +** +** Verify that an Abort can happen. Assert if an Abort at this point +** might cause database corruption. This opcode only appears in debugging +** builds. +** +** An Abort is safe if either there have been no writes, or if there is +** an active statement journal. +*/ +case OP_Abortable: { + sqlite3VdbeAssertAbortable(p); + break; +} +#endif + /* Opcode: Noop * * * * * ** ** Do nothing. This instruction is often useful as a jump @@ -7136,8 +7481,9 @@ case OP_CursorHint: { ** This opcode records information from the optimizer. It is the ** the same as a no-op. This opcodesnever appears in a real VM program. */ -default: { /* This is really OP_Noop and OP_Explain */ +default: { /* This is really OP_Noop, OP_Explain */ assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); + break; } @@ -7151,7 +7497,7 @@ default: { /* This is really OP_Noop and OP_Explain */ #ifdef VDBE_PROFILE { - u64 endTime = sqlite3Hwtime(); + u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); if( endTime>start ) pOrigOp->cycles += endTime - start; pOrigOp->cnt++; } diff --git a/src/vdbe.h b/src/vdbe.h index 889ca549a3..b6b3204790 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -73,7 +73,8 @@ struct VdbeOp { u64 cycles; /* Total time spent executing this instruction */ #endif #ifdef SQLITE_VDBE_COVERAGE - int iSrcLine; /* Source-code line that generated this opcode */ + u32 iSrcLine; /* Source-code line that generated this opcode + ** with flags in the upper 8 bits */ #endif }; typedef struct VdbeOp VdbeOp; @@ -127,6 +128,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ +#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 @@ -196,7 +198,24 @@ void sqlite3VdbeEndCoroutine(Vdbe*,int); # define sqlite3VdbeVerifyNoMallocRequired(A,B) # define sqlite3VdbeVerifyNoResultRow(A) #endif -VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); +#if defined(SQLITE_DEBUG) + void sqlite3VdbeVerifyAbortable(Vdbe *p, int); +#else +# define sqlite3VdbeVerifyAbortable(A,B) +#endif +VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); +#ifndef SQLITE_OMIT_EXPLAIN + void sqlite3VdbeExplain(Parse*,u8,const char*,...); + void sqlite3VdbeExplainPop(Parse*); + int sqlite3VdbeExplainParent(Parse*); +# define ExplainQueryPlan(P) sqlite3VdbeExplain P +# define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) +# define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) +#else +# define ExplainQueryPlan(P) +# define ExplainQueryPlanPop(P) +# define ExplainQueryPlanParent(P) 0 +#endif void sqlite3VdbeAddParseSchemaOp(Parse*,int,char*); void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8); void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); @@ -240,6 +259,7 @@ void sqlite3VdbeSetVarmask(Vdbe*, int); char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); +int sqlite3BlobCompare(const Mem*, const Mem*); void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); @@ -295,23 +315,52 @@ int sqlite3NotPureFunc(sqlite3_context*); ** ** VdbeCoverageNeverTaken(v) // Previous branch is never taken ** +** VdbeCoverageNeverNull(v) // Previous three-way branch is only +** // taken on the first two ways. The +** // NULL option is not possible +** +** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested +** // in distingishing equal and not-equal. +** ** Every VDBE branch operation must be tagged with one of the macros above. ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and ** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() ** routine in vdbe.c, alerting the developer to the missed tag. +** +** During testing, the test application will invoke +** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback +** routine that is invoked as each bytecode branch is taken. The callback +** contains the sqlite3.c source line number ov the VdbeCoverage macro and +** flags to indicate whether or not the branch was taken. The test application +** is responsible for keeping track of this and reporting byte-code branches +** that are never taken. +** +** See the VdbeBranchTaken() macro and vdbeTakeBranch() function in the +** vdbe.c source file for additional information. */ #ifdef SQLITE_VDBE_COVERAGE void sqlite3VdbeSetLineNumber(Vdbe*,int); # define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) # define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) -# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2); -# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1); +# define VdbeCoverageAlwaysTaken(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000); +# define VdbeCoverageNeverTaken(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000); +# define VdbeCoverageNeverNull(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); +# define VdbeCoverageNeverNullIf(v,x) \ + if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); +# define VdbeCoverageEqNe(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000); # define VDBE_OFFSET_LINENO(x) (__LINE__+x) #else # define VdbeCoverage(v) # define VdbeCoverageIf(v,x) # define VdbeCoverageAlwaysTaken(v) # define VdbeCoverageNeverTaken(v) +# define VdbeCoverageNeverNull(v) +# define VdbeCoverageNeverNullIf(v,x) +# define VdbeCoverageEqNe(v) # define VDBE_OFFSET_LINENO(x) 0 #endif @@ -321,4 +370,8 @@ void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); # define sqlite3VdbeScanStatus(a,b,c,d,e) #endif +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) +void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); +#endif + #endif /* SQLITE_VDBE_H */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index d8e47be500..107e5cab44 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -85,6 +85,7 @@ struct VdbeCursor { Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ + Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ int *aAltMap; /* Mapping from table to index column numbers */ @@ -96,18 +97,18 @@ struct VdbeCursor { u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 ** if there have been no prior seeks on the cursor. */ - /* NB: seekResult does not distinguish between "no seeks have ever occurred - ** on this cursor" and "the most recent seek was an exact match". */ + /* seekResult does not distinguish between "no seeks have ever occurred + ** on this cursor" and "the most recent seek was an exact match". + ** For CURTYPE_PSEUDO, seekResult is the register holding the record */ /* When a new VdbeCursor is allocated, only the fields above are zeroed. ** The fields that follow are uninitialized, and must be individually ** initialized prior to first use. */ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ union { - BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ - sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ - int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ - VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ + BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */ + sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ + VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ u32 iHdrOffset; /* Offset to next unparsed byte of the header */ @@ -168,6 +169,9 @@ struct VdbeFrame { void *token; /* Copy of SubProgram.token */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ AuxData *pAuxData; /* Linked list of auxdata allocations */ +#if SQLITE_DEBUG + u32 iFrameMagic; /* magic number for sanity checking */ +#endif int nCursor; /* Number of entries in apCsr */ int pc; /* Program Counter in parent (calling) frame */ int nOp; /* Size of aOp array */ @@ -178,6 +182,13 @@ struct VdbeFrame { int nDbChange; /* Value of db->nChange */ }; +/* Magic number for sanity checking on VdbeFrame objects */ +#define SQLITE_FRAME_MAGIC 0x879fb71e + +/* +** Return a pointer to the array of registers allocated for use +** by a VdbeFrame. +*/ #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) /* @@ -192,8 +203,6 @@ struct sqlite3_value { int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ - RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ - VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ @@ -208,7 +217,7 @@ struct sqlite3_value { void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ - void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ + u16 mScopyFlags; /* flags value immediately after the shallow copy */ #endif }; @@ -237,8 +246,8 @@ struct sqlite3_value { #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_AffMask 0x001f /* Mask of affinity bits */ -#define MEM_RowSet 0x0020 /* Value is a RowSet object */ -#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ +/* Available 0x0020 */ +/* Available 0x0040 */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0xc1ff /* Mask of type bits */ @@ -265,7 +274,7 @@ struct sqlite3_value { ** that needs to be deallocated to avoid a leak. */ #define VdbeMemDynamic(X) \ - (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) + (((X)->flags&(MEM_Agg|MEM_Dyn))!=0) /* ** Clear any existing type flags from a Mem and replace them with f @@ -317,7 +326,6 @@ struct sqlite3_context { int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 skipFlag; /* Skip accumulator loading if true */ - u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ u8 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; @@ -380,14 +388,15 @@ struct Vdbe { int nOp; /* Number of instructions in the program */ #ifdef SQLITE_DEBUG int rcApp; /* errcode set by sqlite3_result_error_code() */ + u32 nWrite; /* Number of write operations that have occurred */ #endif u16 nResColumn; /* Number of columns in one row of the result set */ u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ - bft expired:1; /* True if the VM needs to be recompiled */ - bft doingRerun:1; /* True if rerunning after an auto-reprepare */ + bft expired:2; /* 1: recompile VM immediately 2: when convenient */ bft explain:2; /* True if EXPLAIN present on SQL command */ + bft doingRerun:1; /* True if rerunning after an auto-reprepare */ bft changeCntOn:1; /* True to update the change-counter */ bft runOnlyOnce:1; /* Automatically expire on reset */ bft usesStmtJournal:1; /* True if uses a statement journal */ @@ -448,9 +457,6 @@ void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); int sqlite3VdbeCursorRestore(VdbeCursor*); -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) -void sqlite3VdbePrintOp(FILE*, int, Op*); -#endif u32 sqlite3VdbeSerialTypeLen(u32); u8 sqlite3VdbeOneByteSerialTypeLen(u8); u32 sqlite3VdbeSerialType(Mem*, int, u32*); @@ -481,12 +487,16 @@ void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetZeroBlob(Mem*,int); -void sqlite3VdbeMemSetRowSet(Mem*); +#ifdef SQLITE_DEBUG +int sqlite3VdbeMemIsRowSet(const Mem*); +#endif +int sqlite3VdbeMemSetRowSet(Mem*); int sqlite3VdbeMemMakeWriteable(Mem*); int sqlite3VdbeMemStringify(Mem*, u8, u8); i64 sqlite3VdbeIntValue(Mem*); int sqlite3VdbeMemIntegerify(Mem*); double sqlite3VdbeRealValue(Mem*); +int sqlite3VdbeBooleanValue(Mem*, int ifNull); void sqlite3VdbeIntegerAffinity(Mem*); int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemNumerify(Mem*); @@ -494,11 +504,18 @@ void sqlite3VdbeMemCast(Mem*,u8,u8); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); void sqlite3VdbeMemRelease(Mem *p); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); +#ifndef SQLITE_OMIT_WINDOWFUNC +int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); +#endif const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); int sqlite3VdbeCloseStatement(Vdbe *, int); -void sqlite3VdbeFrameDelete(VdbeFrame*); +#ifdef SQLITE_DEBUG +int sqlite3VdbeFrameIsValid(VdbeFrame*); +#endif +void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ +void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); @@ -514,6 +531,14 @@ int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); +#ifdef SQLITE_DEBUG + void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); + void sqlite3VdbeAssertAbortable(Vdbe*); +#else +# define sqlite3VdbeIncrWriteCounter(V,C) +# define sqlite3VdbeAssertAbortable(V) +#endif + #if !defined(SQLITE_OMIT_SHARED_CACHE) void sqlite3VdbeEnter(Vdbe*); #else diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 3f4ef8f6a9..b21f70e7e0 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -268,6 +268,11 @@ int sqlite3_value_type(sqlite3_value* pVal){ return aType[pVal->flags&MEM_AffMask]; } +/* Return true if a parameter to xUpdate represents an unchanged column */ +int sqlite3_value_nochange(sqlite3_value *pVal){ + return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); +} + /* Make a copy of an sqlite3_value object */ sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ @@ -367,14 +372,12 @@ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; - pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; - pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif @@ -398,7 +401,8 @@ void sqlite3_result_pointer( ){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); - sqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemRelease(pOut); + pOut->flags = MEM_Null; sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ @@ -479,8 +483,7 @@ int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ return SQLITE_OK; } void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ - pCtx->isError = errCode; - pCtx->fErrorOrAux = 1; + pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; #endif @@ -494,7 +497,6 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; - pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, SQLITE_UTF8, SQLITE_STATIC); } @@ -504,7 +506,6 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM_BKPT; - pCtx->fErrorOrAux = 1; sqlite3OomFault(pCtx->pOut->db); } @@ -744,6 +745,25 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ return p->pOut->db; } +/* +** If this routine is invoked from within an xColumn method of a virtual +** table, then it returns true if and only if the the call is during an +** UPDATE operation and the value of the column will not be modified +** by the UPDATE. +** +** If this routine is called from any context other than within the +** xColumn method of a virtual table, then the return value is meaningless +** and arbitrary. +** +** Virtual table implements might use this routine to optimize their +** performance by substituting a NULL result, or some other light-weight +** value, as a signal to the xUpdate routine that the column is unchanged. +*/ +int sqlite3_vtab_nochange(sqlite3_context *p){ + assert( p ); + return sqlite3_value_nochange(p->pOut); +} + /* ** Return the current time for a statement. If the current time ** is requested more than once within the same run of a single prepared @@ -767,28 +787,6 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ return *piTime; } -/* -** The following is the implementation of an SQL function that always -** fails with an error message stating that the function is used in the -** wrong context. The sqlite3_overload_function() API might construct -** SQL function that use this routine so that the functions will exist -** for name resolution but are actually overloaded by the xFindFunction -** method of virtual tables. -*/ -void sqlite3InvalidFunction( - sqlite3_context *context, /* The function calling context */ - int NotUsed, /* Number of arguments to the function */ - sqlite3_value **NotUsed2 /* Value of each argument */ -){ - const char *zName = context->pFunc->zName; - char *zErr; - UNUSED_PARAMETER2(NotUsed, NotUsed2); - zErr = sqlite3_mprintf( - "unable to use function %s in the requested context", zName); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); -} - /* ** Create a new aggregate context for p and return a pointer to ** its pMem->z element. @@ -892,10 +890,7 @@ void sqlite3_set_auxdata( pAuxData->iAuxArg = iArg; pAuxData->pNextAux = pVdbe->pAuxData; pVdbe->pAuxData = pAuxData; - if( pCtx->fErrorOrAux==0 ){ - pCtx->isError = 0; - pCtx->fErrorOrAux = 1; - } + if( pCtx->isError==0 ) pCtx->isError = -1; }else if( pAuxData->xDeleteAux ){ pAuxData->xDeleteAux(pAuxData->pAux); } @@ -975,7 +970,7 @@ static const Mem *columnNullValue(void){ /* .xDel = */ (void(*)(void*))0, #ifdef SQLITE_DEBUG /* .pScopyFrom = */ (Mem*)0, - /* .pFiller = */ (void*)0, + /* .mScopyFlags= */ 0, #endif }; return &nullMem; @@ -1651,7 +1646,9 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ Vdbe *pVdbe = (Vdbe*)pStmt; u32 v; #ifdef SQLITE_ENABLE_API_ARMOR - if( !pStmt ){ + if( !pStmt + || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter))) + ){ (void)SQLITE_MISUSE_BKPT; return 0; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index efa32d1ee4..5630375487 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -33,10 +33,12 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ db->pVdbe = p; p->magic = VDBE_MAGIC_INIT; p->pParse = pParse; + pParse->pVdbe = p; assert( pParse->aLabel==0 ); assert( pParse->nLabel==0 ); assert( pParse->nOpAlloc==0 ); assert( pParse->szOpAlloc==0 ); + sqlite3VdbeAddOp2(p, OP_Init, 0, 1); return p; } @@ -191,14 +193,6 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ - int jj, kk; - Parse *pParse = p->pParse; - for(jj=kk=0; jjnColCache; jj++){ - struct yColCache *x = pParse->aColCache + jj; - printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn); - kk++; - } - if( kk ) printf("\n"); sqlite3VdbePrintOp(0, i, &p->aOp[i]); test_addop_breakpoint(); } @@ -301,6 +295,49 @@ int sqlite3VdbeAddOp4Dup8( return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); } +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Return the address of the current EXPLAIN QUERY PLAN baseline. +** 0 means "none". +*/ +int sqlite3VdbeExplainParent(Parse *pParse){ + VdbeOp *pOp; + if( pParse->addrExplain==0 ) return 0; + pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain); + return pOp->p2; +} + +/* +** Add a new OP_Explain opcode. +** +** If the bPush flag is true, then make this opcode the parent for +** subsequent Explains until sqlite3VdbeExplainPop() is called. +*/ +void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ + if( pParse->explain==2 ){ + char *zMsg; + Vdbe *v; + va_list ap; + int iThis; + va_start(ap, zFmt); + zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); + va_end(ap); + v = pParse->pVdbe; + iThis = v->nOp; + sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, + zMsg, P4_DYNAMIC); + if( bPush) pParse->addrExplain = iThis; + } +} + +/* +** Pop the EXPLAIN QUERY PLAN stack one level. +*/ +void sqlite3VdbeExplainPop(Parse *pParse){ + pParse->addrExplain = sqlite3VdbeExplainParent(pParse); +} +#endif /* SQLITE_OMIT_EXPLAIN */ + /* ** Add an OP_ParseSchema opcode. This routine is broken out from ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees @@ -392,6 +429,12 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ assert( jnLabel ); assert( j>=0 ); if( p->aLabel ){ +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + printf("RESOLVE LABEL %d to %d\n", x, v->nOp); + } +#endif + assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */ p->aLabel[j] = v->nOp; } } @@ -492,7 +535,8 @@ static Op *opIterNext(VdbeOpIter *p){ ** * OP_VUpdate ** * OP_VRename ** * OP_FkCounter with P2==0 (immediate foreign key constraint) -** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...) +** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine +** (for CREATE TABLE AS SELECT ...) ** ** Then check that the value of Parse.mayAbort is true if an ** ABORT may be thrown, or false otherwise. Return true if it does @@ -520,7 +564,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ hasAbort = 1; break; } - if( opcode==OP_CreateTable ) hasCreateTable = 1; + if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1; if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; #ifndef SQLITE_OMIT_FOREIGN_KEY if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ @@ -540,6 +584,32 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ } #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ +#ifdef SQLITE_DEBUG +/* +** Increment the nWrite counter in the VDBE if the cursor is not an +** ephemeral cursor, or if the cursor argument is NULL. +*/ +void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){ + if( pC==0 + || (pC->eCurType!=CURTYPE_SORTER + && pC->eCurType!=CURTYPE_PSEUDO + && !pC->isEphemeral) + ){ + p->nWrite++; + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Assert if an Abort at this point in time might result in a corrupt +** database. +*/ +void sqlite3VdbeAssertAbortable(Vdbe *p){ + assert( p->nWrite==0 || p->usesStmtJournal ); +} +#endif + /* ** This routine is called after all opcodes have been inserted. It loops ** through all the opcodes and fixes up some details. @@ -600,7 +670,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ break; } case OP_Next: - case OP_NextIfOpen: case OP_SorterNext: { pOp->p4.xAdvance = sqlite3BtreeNext; pOp->p4type = P4_ADVANCE; @@ -610,8 +679,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ assert( pOp->p2>=0 ); break; } - case OP_Prev: - case OP_PrevIfOpen: { + case OP_Prev: { pOp->p4.xAdvance = sqlite3BtreePrevious; pOp->p4type = P4_ADVANCE; /* The code generator never codes any of these opcodes as a jump @@ -699,6 +767,17 @@ void sqlite3VdbeVerifyNoResultRow(Vdbe *p){ } #endif +/* +** Generate code (a single OP_Abortable opcode) that will +** verify that the VDBE program can safely call Abort in the current +** context. +*/ +#if defined(SQLITE_DEBUG) +void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){ + if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable); +} +#endif + /* ** This function returns a pointer to the array of opcodes associated with ** the Vdbe passed as the first argument. It is the callers responsibility @@ -865,6 +944,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ case P4_REAL: case P4_INT64: case P4_DYNAMIC: + case P4_DYNBLOB: case P4_INTARRAY: { sqlite3DbFree(db, p4); break; @@ -1242,23 +1322,23 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){ const char *zOp = 0; switch( pExpr->op ){ case TK_STRING: - sqlite3XPrintf(p, "%Q", pExpr->u.zToken); + sqlite3_str_appendf(p, "%Q", pExpr->u.zToken); break; case TK_INTEGER: - sqlite3XPrintf(p, "%d", pExpr->u.iValue); + sqlite3_str_appendf(p, "%d", pExpr->u.iValue); break; case TK_NULL: - sqlite3XPrintf(p, "NULL"); + sqlite3_str_appendf(p, "NULL"); break; case TK_REGISTER: { - sqlite3XPrintf(p, "r[%d]", pExpr->iTable); + sqlite3_str_appendf(p, "r[%d]", pExpr->iTable); break; } case TK_COLUMN: { if( pExpr->iColumn<0 ){ - sqlite3XPrintf(p, "rowid"); + sqlite3_str_appendf(p, "rowid"); }else{ - sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn); + sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn); } break; } @@ -1290,18 +1370,18 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){ case TK_NOTNULL: zOp = "NOTNULL"; break; default: - sqlite3XPrintf(p, "%s", "expr"); + sqlite3_str_appendf(p, "%s", "expr"); break; } if( zOp ){ - sqlite3XPrintf(p, "%s(", zOp); + sqlite3_str_appendf(p, "%s(", zOp); displayP4Expr(p, pExpr->pLeft); if( pExpr->pRight ){ - sqlite3StrAccumAppend(p, ",", 1); + sqlite3_str_append(p, ",", 1); displayP4Expr(p, pExpr->pRight); } - sqlite3StrAccumAppend(p, ")", 1); + sqlite3_str_append(p, ")", 1); } } #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ @@ -1322,14 +1402,15 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ int j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; assert( pKeyInfo->aSortOrder!=0 ); - sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField); + sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); for(j=0; jnKeyField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : ""; if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; - sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl); + sqlite3_str_appendf(&x, ",%s%s", + pKeyInfo->aSortOrder[j] ? "-" : "", zColl); } - sqlite3StrAccumAppend(&x, ")", 1); + sqlite3_str_append(&x, ")", 1); break; } #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -1340,31 +1421,31 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ #endif case P4_COLLSEQ: { CollSeq *pColl = pOp->p4.pColl; - sqlite3XPrintf(&x, "(%.20s)", pColl->zName); + sqlite3_str_appendf(&x, "(%.20s)", pColl->zName); break; } case P4_FUNCDEF: { FuncDef *pDef = pOp->p4.pFunc; - sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) case P4_FUNCCTX: { FuncDef *pDef = pOp->p4.pCtx->pFunc; - sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } #endif case P4_INT64: { - sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64); + sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); break; } case P4_INT32: { - sqlite3XPrintf(&x, "%d", pOp->p4.i); + sqlite3_str_appendf(&x, "%d", pOp->p4.i); break; } case P4_REAL: { - sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal); + sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); break; } case P4_MEM: { @@ -1372,9 +1453,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & MEM_Int ){ - sqlite3XPrintf(&x, "%lld", pMem->u.i); + sqlite3_str_appendf(&x, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ - sqlite3XPrintf(&x, "%.16g", pMem->u.r); + sqlite3_str_appendf(&x, "%.16g", pMem->u.r); }else if( pMem->flags & MEM_Null ){ zP4 = "NULL"; }else{ @@ -1386,7 +1467,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ #ifndef SQLITE_OMIT_VIRTUALTABLE case P4_VTAB: { sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; - sqlite3XPrintf(&x, "vtab:%p", pVtab); + sqlite3_str_appendf(&x, "vtab:%p", pVtab); break; } #endif @@ -1395,23 +1476,24 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ int *ai = pOp->p4.ai; int n = ai[0]; /* The first element of an INTARRAY is always the ** count of the number of elements to follow */ - for(i=1; ip4.pTab->zName); + sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName); break; } default: { @@ -1512,7 +1594,7 @@ void sqlite3VdbeLeave(Vdbe *p){ /* ** Print a single opcode. This routine is used for debugging only. */ -void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ +void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ char *zP4; char zPtr[50]; char zCom[100]; @@ -1581,9 +1663,8 @@ static void releaseMemArray(Mem *p, int N){ */ testcase( p->flags & MEM_Agg ); testcase( p->flags & MEM_Dyn ); - testcase( p->flags & MEM_Frame ); - testcase( p->flags & MEM_RowSet ); - if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ + testcase( p->xDel==sqlite3VdbeFrameMemDel ); + if( p->flags&(MEM_Agg|MEM_Dyn) ){ sqlite3VdbeMemRelease(p); }else if( p->szMalloc ){ sqlite3DbFreeNN(db, p->zMalloc); @@ -1595,6 +1676,35 @@ static void releaseMemArray(Mem *p, int N){ } } +#ifdef SQLITE_DEBUG +/* +** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is +** and false if something is wrong. +** +** This routine is intended for use inside of assert() statements only. +*/ +int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){ + if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0; + return 1; +} +#endif + + +/* +** This is a destructor on a Mem object (which is really an sqlite3_value) +** that deletes the Frame object that is attached to it as a blob. +** +** This routine does not delete the Frame right away. It merely adds the +** frame to a list of frames to be deleted when the Vdbe halts. +*/ +void sqlite3VdbeFrameMemDel(void *pArg){ + VdbeFrame *pFrame = (VdbeFrame*)pArg; + assert( sqlite3VdbeFrameIsValid(pFrame) ); + pFrame->pParent = pFrame->v->pDelFrame; + pFrame->v->pDelFrame = pFrame; +} + + /* ** Delete a VdbeFrame object and its contents. VdbeFrame objects are ** allocated by the OP_Program opcode in sqlite3VdbeExec(). @@ -1603,6 +1713,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){ int i; Mem *aMem = VdbeFrameMem(p); VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; + assert( sqlite3VdbeFrameIsValid(p) ); for(i=0; inChildCsr; i++){ sqlite3VdbeFreeCursor(p->v, apCsr[i]); } @@ -1623,6 +1734,9 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){ ** p->explain==2, only OP_Explain instructions are listed and these ** are shown in a different format. p->explain==2 is used to implement ** EXPLAIN QUERY PLAN. +** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers +** are also shown, so that the boundaries between the main program and +** each trigger are clear. ** ** When p->explain==1, first the main program is listed, then each of ** the trigger subprograms are listed one by one. @@ -1638,6 +1752,8 @@ int sqlite3VdbeList( int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ Mem *pMem = &p->aMem[1]; /* First Mem of result set */ + int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0); + Op *pOp = 0; assert( p->explain ); assert( p->magic==VDBE_MAGIC_RUN ); @@ -1650,7 +1766,7 @@ int sqlite3VdbeList( releaseMemArray(pMem, 8); p->pResultSet = 0; - if( p->rc==SQLITE_NOMEM_BKPT ){ + if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ sqlite3OomFault(db); @@ -1665,7 +1781,7 @@ int sqlite3VdbeList( ** encountered, but p->pc will eventually catch up to nRow. */ nRow = p->nOp; - if( p->explain==1 ){ + if( bListSubprogs ){ /* The first 8 memory cells are used for the result set. So we will ** commandeer the 9th cell to use as storage for an array of pointers ** to trigger subprograms. The VDBE is guaranteed to have at least 9 @@ -1683,19 +1799,13 @@ int sqlite3VdbeList( } } - do{ + while(1){ /* Loop exits via break */ i = p->pc++; - }while( iexplain==2 && p->aOp[i].opcode!=OP_Explain ); - if( i>=nRow ){ - p->rc = SQLITE_OK; - rc = SQLITE_DONE; - }else if( db->u1.isInterrupted ){ - p->rc = SQLITE_INTERRUPT; - rc = SQLITE_ERROR; - sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); - }else{ - char *zP4; - Op *pOp; + if( i>=nRow ){ + p->rc = SQLITE_OK; + rc = SQLITE_DONE; + break; + } if( inOp ){ /* The output line number is small enough that we are still in the ** main program. */ @@ -1710,94 +1820,113 @@ int sqlite3VdbeList( } pOp = &apSub[j]->aOp[i]; } - if( p->explain==1 ){ - pMem->flags = MEM_Int; - pMem->u.i = i; /* Program counter */ - pMem++; - - pMem->flags = MEM_Static|MEM_Str|MEM_Term; - pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ - assert( pMem->z!=0 ); - pMem->n = sqlite3Strlen30(pMem->z); - pMem->enc = SQLITE_UTF8; - pMem++; - /* When an OP_Program opcode is encounter (the only opcode that has - ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms - ** kept in p->aMem[9].z to hold the new program - assuming this subprogram - ** has not already been seen. - */ - if( pOp->p4type==P4_SUBPROGRAM ){ - int nByte = (nSub+1)*sizeof(SubProgram*); - int j; - for(j=0; jp4.pProgram ) break; - } - if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){ - apSub = (SubProgram **)pSub->z; - apSub[nSub++] = pOp->p4.pProgram; - pSub->flags |= MEM_Blob; - pSub->n = nSub*sizeof(SubProgram*); + /* When an OP_Program opcode is encounter (the only opcode that has + ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms + ** kept in p->aMem[9].z to hold the new program - assuming this subprogram + ** has not already been seen. + */ + if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){ + int nByte = (nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jp4.pProgram ) break; + } + if( j==nSub ){ + p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + break; } + apSub = (SubProgram **)pSub->z; + apSub[nSub++] = pOp->p4.pProgram; + pSub->flags |= MEM_Blob; + pSub->n = nSub*sizeof(SubProgram*); + nRow += pOp->p4.pProgram->nOp; } } + if( p->explain<2 ) break; + if( pOp->opcode==OP_Explain ) break; + if( pOp->opcode==OP_Init && p->pc>1 ) break; + } - pMem->flags = MEM_Int; - pMem->u.i = pOp->p1; /* P1 */ - pMem++; - - pMem->flags = MEM_Int; - pMem->u.i = pOp->p2; /* P2 */ - pMem++; - - pMem->flags = MEM_Int; - pMem->u.i = pOp->p3; /* P3 */ - pMem++; - - if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ - assert( p->db->mallocFailed ); - return SQLITE_ERROR; - } - pMem->flags = MEM_Str|MEM_Term; - zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); - if( zP4!=pMem->z ){ - pMem->n = 0; - sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); + if( rc==SQLITE_OK ){ + if( db->u1.isInterrupted ){ + p->rc = SQLITE_INTERRUPT; + rc = SQLITE_ERROR; + sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); }else{ - assert( pMem->z!=0 ); - pMem->n = sqlite3Strlen30(pMem->z); - pMem->enc = SQLITE_UTF8; - } - pMem++; - - if( p->explain==1 ){ - if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ - assert( p->db->mallocFailed ); - return SQLITE_ERROR; + char *zP4; + if( p->explain==1 ){ + pMem->flags = MEM_Int; + pMem->u.i = i; /* Program counter */ + pMem++; + + pMem->flags = MEM_Static|MEM_Str|MEM_Term; + pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ + assert( pMem->z!=0 ); + pMem->n = sqlite3Strlen30(pMem->z); + pMem->enc = SQLITE_UTF8; + pMem++; } - pMem->flags = MEM_Str|MEM_Term; - pMem->n = 2; - sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ - pMem->enc = SQLITE_UTF8; + + pMem->flags = MEM_Int; + pMem->u.i = pOp->p1; /* P1 */ pMem++; - -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ + + pMem->flags = MEM_Int; + pMem->u.i = pOp->p2; /* P2 */ + pMem++; + + pMem->flags = MEM_Int; + pMem->u.i = pOp->p3; /* P3 */ + pMem++; + + if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ assert( p->db->mallocFailed ); return SQLITE_ERROR; } pMem->flags = MEM_Str|MEM_Term; - pMem->n = displayComment(pOp, zP4, pMem->z, 500); - pMem->enc = SQLITE_UTF8; -#else - pMem->flags = MEM_Null; /* Comment */ -#endif - } + zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); + if( zP4!=pMem->z ){ + pMem->n = 0; + sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); + }else{ + assert( pMem->z!=0 ); + pMem->n = sqlite3Strlen30(pMem->z); + pMem->enc = SQLITE_UTF8; + } + pMem++; - p->nResColumn = 8 - 4*(p->explain-1); - p->pResultSet = &p->aMem[1]; - p->rc = SQLITE_OK; - rc = SQLITE_ROW; + if( p->explain==1 ){ + if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ + assert( p->db->mallocFailed ); + return SQLITE_ERROR; + } + pMem->flags = MEM_Str|MEM_Term; + pMem->n = 2; + sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ + pMem->enc = SQLITE_UTF8; + pMem++; + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ + assert( p->db->mallocFailed ); + return SQLITE_ERROR; + } + pMem->flags = MEM_Str|MEM_Term; + pMem->n = displayComment(pOp, zP4, pMem->z, 500); + pMem->enc = SQLITE_UTF8; +#else + pMem->flags = MEM_Null; /* Comment */ +#endif + } + + p->nResColumn = 8 - 4*(p->explain-1); + p->pResultSet = &p->aMem[1]; + p->rc = SQLITE_OK; + rc = SQLITE_ROW; + } } return rc; } @@ -2159,27 +2288,6 @@ static void closeAllCursors(Vdbe *p){ assert( p->pAuxData==0 ); } -/* -** Clean up the VM after a single run. -*/ -static void Cleanup(Vdbe *p){ - sqlite3 *db = p->db; - -#ifdef SQLITE_DEBUG - /* Execute assert() statements to ensure that the Vdbe.apCsr[] and - ** Vdbe.aMem[] arrays have already been cleaned up. */ - int i; - if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); - if( p->aMem ){ - for(i=0; inMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); - } -#endif - - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; - p->pResultSet = 0; -} - /* ** Set the number of result columns that will be returned by this SQL ** statement. This is now set at compile time, rather than during @@ -2288,6 +2396,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ pPager = sqlite3BtreePager(pBt); if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF && aMJNeeded[sqlite3PagerGetJournalMode(pPager)] + && sqlite3PagerIsMemdb(pPager)==0 ){ assert( i!=1 ); nTrans++; @@ -2888,6 +2997,10 @@ static void vdbeInvokeSqllog(Vdbe *v){ ** VDBE_MAGIC_INIT. */ int sqlite3VdbeReset(Vdbe *p){ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + int i; +#endif + sqlite3 *db; db = p->db; @@ -2897,7 +3010,7 @@ int sqlite3VdbeReset(Vdbe *p){ */ sqlite3VdbeHalt(p); - /* If the VDBE has be run even partially, then transfer the error code + /* If the VDBE has been run even partially, then transfer the error code ** and error message from the VDBE into the main database structure. But ** if the VDBE has just been set to run but has not actually executed any ** instructions yet, leave the main database error information unchanged. @@ -2905,8 +3018,6 @@ int sqlite3VdbeReset(Vdbe *p){ if( p->pc>=0 ){ vdbeInvokeSqllog(p); sqlite3VdbeTransferError(p); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; if( p->runOnlyOnce ) p->expired = 1; }else if( p->rc && p->expired ){ /* The expired flag was set on the VDBE before the first call @@ -2914,13 +3025,24 @@ int sqlite3VdbeReset(Vdbe *p){ ** called), set the database error in this case as well. */ sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; } - /* Reclaim all memory used by the VDBE + /* Reset register contents and reclaim error message memory. */ - Cleanup(p); +#ifdef SQLITE_DEBUG + /* Execute assert() statements to ensure that the Vdbe.apCsr[] and + ** Vdbe.aMem[] arrays have already been cleaned up. */ + if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); + if( p->aMem ){ + for(i=0; inMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); + } +#endif + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + p->pResultSet = 0; +#ifdef SQLITE_DEBUG + p->nWrite = 0; +#endif /* Save profiling information from this VDBE run. */ @@ -2928,7 +3050,6 @@ int sqlite3VdbeReset(Vdbe *p){ { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ - int i; fprintf(out, "---- "); for(i=0; inOp; i++){ fprintf(out, "%02x", p->aOp[i].opcode); @@ -3054,7 +3175,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ void sqlite3VdbeDelete(Vdbe *p){ sqlite3 *db; - if( NEVER(p==0) ) return; + assert( p!=0 ); db = p->db; assert( sqlite3_mutex_held(db->mutex) ); sqlite3VdbeClearObject(db, p); @@ -3141,19 +3262,18 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){ */ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ VdbeCursor *p = *pp; - if( p->eCurType==CURTYPE_BTREE ){ - if( p->deferredMoveto ){ - int iMap; - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ - *pp = p->pAltCursor; - *piCol = iMap - 1; - return SQLITE_OK; - } - return handleDeferredMoveto(p); - } - if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return handleMovedCursor(p); + assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); + if( p->deferredMoveto ){ + int iMap; + if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ + *pp = p->pAltCursor; + *piCol = iMap - 1; + return SQLITE_OK; } + return handleDeferredMoveto(p); + } + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + return handleMovedCursor(p); } return SQLITE_OK; } @@ -3451,7 +3571,13 @@ u32 sqlite3VdbeSerialGet( Mem *pMem /* Memory cell to write value into */ ){ switch( serial_type ){ - case 10: /* Reserved for future use */ + case 10: { /* Internal use only: NULL with virtual table + ** UPDATE no-change flag set */ + pMem->flags = MEM_Null|MEM_Zero; + pMem->n = 0; + pMem->u.nZero = 0; + break; + } case 11: /* Reserved for future use */ case 0: { /* Null */ /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ @@ -3796,7 +3922,7 @@ static int isAllZero(const char *z, int n){ ** is less than, equal to, or greater than the second, respectively. ** If one blob is a prefix of the other, then the shorter is the lessor. */ -static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ +SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ int c; int n1 = pB1->n; int n2 = pB2->n; @@ -3839,13 +3965,10 @@ static int sqlite3IntFloatCompare(i64 i, double r){ i64 y; double s; if( r<-9223372036854775808.0 ) return +1; - if( r>9223372036854775807.0 ) return -1; + if( r>=9223372036854775808.0 ) return -1; y = (i64)r; if( iy ){ - if( y==SMALLEST_INT64 && r>0.0 ) return -1; - return +1; - } + if( i>y ) return +1; s = (double)i; if( sr ) return +1; @@ -3869,7 +3992,7 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ f1 = pMem1->flags; f2 = pMem2->flags; combined_flags = f1|f2; - assert( (combined_flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. @@ -4014,7 +4137,7 @@ int sqlite3VdbeRecordCompareWithSkip( u32 idx1; /* Offset of first type in header */ int rc = 0; /* Return value */ Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ - KeyInfo *pKeyInfo = pPKey2->pKeyInfo; + KeyInfo *pKeyInfo; const unsigned char *aKey1 = (const unsigned char *)pKey1; Mem mem1; @@ -4109,7 +4232,7 @@ int sqlite3VdbeRecordCompareWithSkip( if( (d1+mem1.n) > (unsigned)nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ - }else if( pKeyInfo->aColl[i] ){ + }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){ mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; mem1.flags = MEM_Str; @@ -4160,7 +4283,7 @@ int sqlite3VdbeRecordCompareWithSkip( } if( rc!=0 ){ - if( pKeyInfo->aSortOrder[i] ){ + if( pPKey2->pKeyInfo->aSortOrder[i] ){ rc = -rc; } assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); @@ -4169,10 +4292,11 @@ int sqlite3VdbeRecordCompareWithSkip( } i++; + if( i==pPKey2->nField ) break; pRhs++; d1 += sqlite3VdbeSerialTypeLen(serial_type); idx1 += sqlite3VarintLen(serial_type); - }while( idx1<(unsigned)szHdr1 && inField && d1<=(unsigned)nKey1 ); + }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a @@ -4184,7 +4308,7 @@ int sqlite3VdbeRecordCompareWithSkip( ** value. */ assert( CORRUPT_DB || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) - || pKeyInfo->db->mallocFailed + || pPKey2->pKeyInfo->db->mallocFailed ); pPKey2->eqSeen = 1; return pPKey2->default_rc; @@ -4435,7 +4559,9 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ (void)getVarint32((u8*)m.z, szHdr); testcase( szHdr==3 ); testcase( szHdr==m.n ); - if( unlikely(szHdr<3 || (int)szHdr>m.n) ){ + testcase( szHdr>0x7fffffff ); + assert( m.n>=0 ); + if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ goto idx_rowid_corruption; } @@ -4510,7 +4636,7 @@ int sqlite3VdbeIdxKeyCompare( if( rc ){ return rc; } - *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); + *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); sqlite3VdbeMemRelease(&m); return SQLITE_OK; } @@ -4542,11 +4668,19 @@ void sqlite3VdbeCountChanges(Vdbe *v){ ** programs obsolete. Removing user-defined functions or collating ** sequences, or changing an authorization function are the types of ** things that make prepared statements obsolete. +** +** If iCode is 1, then expiration is advisory. The statement should +** be reprepared before being restarted, but if it is already running +** it is allowed to run to completion. +** +** Internally, this function just sets the Vdbe.expired flag on all +** prepared statements. The flag is set to 1 for an immediate expiration +** and set to 2 for an advisory expiration. */ -void sqlite3ExpirePreparedStatements(sqlite3 *db){ +void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ Vdbe *p; for(p = db->pVdbe; p; p=p->pNext){ - p->expired = 1; + p->expired = iCode+1; } } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 8d75f8ab01..4279792696 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -63,11 +63,12 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ v->aMem[1].u.i = iRow; /* If the statement has been run before (and is paused at the OP_ResultRow) - ** then back it up to the point where it does the OP_SeekRowid. This could + ** then back it up to the point where it does the OP_NotExists. This could ** have been down with an extra OP_Goto, but simply setting the program ** counter is faster. */ - if( v->pc>3 ){ - v->pc = 3; + if( v->pc>4 ){ + v->pc = 4; + assert( v->aOp[v->pc].opcode==OP_NotExists ); rc = sqlite3VdbeExec(v); }else{ rc = sqlite3_step(p->pStmt); @@ -275,7 +276,8 @@ int sqlite3_blob_open( sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, pTab->pSchema->schema_cookie, pTab->pSchema->iGeneration); - sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeChangeP5(v, 1); + assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed ); aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); /* Make sure a mutex is held on the table to be accessed */ @@ -290,7 +292,7 @@ int sqlite3_blob_open( aOp[0].p1 = iDb; aOp[0].p2 = pTab->tnum; aOp[0].p3 = wrFlag; - sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); + sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); } if( db->mallocFailed==0 ){ #endif diff --git a/src/vdbemem.c b/src/vdbemem.c index 346c1fb10b..d204dc8d27 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -42,8 +42,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ if( p->flags & MEM_Null ){ /* Cannot be both MEM_Null and some other type */ - assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob - |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 ); + assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); /* If MEM_Null is set, then either the value is a pure NULL (the usual ** case) or it is a pointer set using sqlite3_bind_pointer() or @@ -93,6 +92,51 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ } #endif +#ifdef SQLITE_DEBUG +/* +** Check that string value of pMem agrees with its integer or real value. +** +** A single int or real value always converts to the same strings. But +** many different strings can be converted into the same int or real. +** If a table contains a numeric value and an index is based on the +** corresponding string value, then it is important that the string be +** derived from the numeric value, not the other way around, to ensure +** that the index and table are consistent. See ticket +** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for +** an example. +** +** This routine looks at pMem to verify that if it has both a numeric +** representation and a string representation then the string rep has +** been derived from the numeric and not the other way around. It returns +** true if everything is ok and false if there is a problem. +** +** This routine is for use inside of assert() statements only. +*/ +int sqlite3VdbeMemConsistentDualRep(Mem *p){ + char zBuf[100]; + char *z; + int i, j, incr; + if( (p->flags & MEM_Str)==0 ) return 1; + if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1; + if( p->flags & MEM_Int ){ + sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i); + }else{ + sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r); + } + z = p->z; + i = j = 0; + incr = 1; + if( p->enc!=SQLITE_UTF8 ){ + incr = 2; + if( p->enc==SQLITE_UTF16BE ) z++; + } + while( zBuf[j] ){ + if( zBuf[j++]!=z[i] ) return 0; + i += incr; + } + return 1; +} +#endif /* SQLITE_DEBUG */ /* ** If pMem is an object with a valid string representation, this routine @@ -111,7 +155,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ #ifndef SQLITE_OMIT_UTF16 int rc; #endif - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ @@ -144,7 +188,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ */ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( sqlite3VdbeCheckMemInvariants(pMem) ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); testcase( pMem->db==0 ); /* If the bPreserve flag is set to true, then the memory cell must already @@ -155,7 +199,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( pMem->szMalloc==0 || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); if( n<32 ) n = 32; - if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){ + if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); bPreserve = 0; }else{ @@ -171,7 +215,8 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); } - if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){ + if( bPreserve && pMem->z ){ + assert( pMem->z!=pMem->zMalloc ); memcpy(pMem->zMalloc, pMem->z, pMem->n); } if( (pMem->flags&MEM_Dyn)!=0 ){ @@ -209,6 +254,20 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ return SQLITE_OK; } +/* +** It is already known that pMem contains an unterminated string. +** Add the zero terminator. +*/ +static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ + if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ + return SQLITE_NOMEM_BKPT; + } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->flags |= MEM_Term; + return SQLITE_OK; +} + /* ** Change pMem so that its MEM_Str or MEM_Blob value is stored in ** MEM.zMalloc, where it can be safely written. @@ -217,16 +276,12 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ */ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ if( ExpandBlob(pMem) ) return SQLITE_NOMEM; if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ - if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ - return SQLITE_NOMEM_BKPT; - } - pMem->z[pMem->n] = 0; - pMem->z[pMem->n+1] = 0; - pMem->flags |= MEM_Term; + int rc = vdbeMemAddTerminator(pMem); + if( rc ) return rc; } } pMem->flags &= ~MEM_Ephem; @@ -246,7 +301,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){ int nByte; assert( pMem->flags & MEM_Zero ); assert( pMem->flags&MEM_Blob ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); /* Set nByte to the number of bytes required to store the expanded blob. */ @@ -265,20 +320,6 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){ } #endif -/* -** It is already known that pMem contains an unterminated string. -** Add the zero terminator. -*/ -static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ - if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ - return SQLITE_NOMEM_BKPT; - } - pMem->z[pMem->n] = 0; - pMem->z[pMem->n+1] = 0; - pMem->flags |= MEM_Term; - return SQLITE_OK; -} - /* ** Make sure the given Mem is \u0000 terminated. */ @@ -315,7 +356,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ assert( !(fg&MEM_Zero) ); assert( !(fg&(MEM_Str|MEM_Blob)) ); assert( fg&(MEM_Int|MEM_Real) ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -353,28 +394,55 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ ** otherwise. */ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ - int rc = SQLITE_OK; - if( ALWAYS(pFunc && pFunc->xFinalize) ){ - sqlite3_context ctx; - Mem t; - assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - memset(&ctx, 0, sizeof(ctx)); - memset(&t, 0, sizeof(t)); - t.flags = MEM_Null; - t.db = pMem->db; - ctx.pOut = &t; - ctx.pMem = pMem; - ctx.pFunc = pFunc; - pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ - assert( (pMem->flags & MEM_Dyn)==0 ); - if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); - memcpy(pMem, &t, sizeof(t)); - rc = ctx.isError; - } - return rc; + sqlite3_context ctx; + Mem t; + assert( pFunc!=0 ); + assert( pFunc->xFinalize!=0 ); + assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + memset(&t, 0, sizeof(t)); + t.flags = MEM_Null; + t.db = pMem->db; + ctx.pOut = &t; + ctx.pMem = pMem; + ctx.pFunc = pFunc; + pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ + assert( (pMem->flags & MEM_Dyn)==0 ); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + memcpy(pMem, &t, sizeof(t)); + return ctx.isError; } +/* +** Memory cell pAccum contains the context of an aggregate function. +** This routine calls the xValue method for that function and stores +** the results in memory cell pMem. +** +** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK +** otherwise. +*/ +#ifndef SQLITE_OMIT_WINDOWFUNC +int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ + sqlite3_context ctx; + Mem t; + assert( pFunc!=0 ); + assert( pFunc->xValue!=0 ); + assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); + assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + memset(&t, 0, sizeof(t)); + t.flags = MEM_Null; + t.db = pAccum->db; + sqlite3VdbeMemSetNull(pOut); + ctx.pOut = pOut; + ctx.pMem = pAccum; + ctx.pFunc = pFunc; + pFunc->xValue(&ctx); + return ctx.isError; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + /* ** If the memory cell contains a value that must be freed by ** invoking the external callback in Mem.xDel, then this routine @@ -393,15 +461,8 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ testcase( p->flags & MEM_Dyn ); } if( p->flags&MEM_Dyn ){ - assert( (p->flags&MEM_RowSet)==0 ); assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); p->xDel((void *)p->z); - }else if( p->flags&MEM_RowSet ){ - sqlite3RowSetClear(p->u.pRowSet); - }else if( p->flags&MEM_Frame ){ - VdbeFrame *pFrame = p->u.pFrame; - pFrame->pParent = pFrame->v->pDelFrame; - pFrame->v->pDelFrame = pFrame; } p->flags = MEM_Null; } @@ -532,6 +593,16 @@ double sqlite3VdbeRealValue(Mem *pMem){ } } +/* +** Return 1 if pMem represents true, and return 0 if pMem represents false. +** Return the value ifNull if pMem is NULL. +*/ +int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ + if( pMem->flags & MEM_Int ) return pMem->u.i!=0; + if( pMem->flags & MEM_Null ) return ifNull; + return sqlite3VdbeRealValue(pMem)!=0.0; +} + /* ** The MEM structure is already a MEM_Real. Try to also make it a ** MEM_Int if we can. @@ -539,7 +610,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ void sqlite3VdbeIntegerAffinity(Mem *pMem){ i64 ix; assert( pMem->flags & MEM_Real ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -566,7 +637,7 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){ */ int sqlite3VdbeMemIntegerify(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); pMem->u.i = sqlite3VdbeIntValue(pMem); @@ -587,6 +658,18 @@ int sqlite3VdbeMemRealify(Mem *pMem){ return SQLITE_OK; } +/* Compare a floating point value to an integer. Return true if the two +** values are the same within the precision of the floating point value. +** +** For some versions of GCC on 32-bit machines, if you do the more obvious +** comparison of "r1==(double)i" you sometimes get an answer of false even +** though the r1 and (double)i values are bit-for-bit the same. +*/ +static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ + double r2 = (double)i; + return memcmp(&r1, &r2, sizeof(r1))==0; +} + /* ** Convert pMem so that it has types MEM_Real or MEM_Int or both. ** Invalidate any prior representations. @@ -597,14 +680,21 @@ int sqlite3VdbeMemRealify(Mem *pMem){ */ int sqlite3VdbeMemNumerify(Mem *pMem){ if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ + int rc; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ + rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc); + if( rc==0 ){ MemSetTypeFlag(pMem, MEM_Int); }else{ - pMem->u.r = sqlite3VdbeRealValue(pMem); - MemSetTypeFlag(pMem, MEM_Real); - sqlite3VdbeIntegerAffinity(pMem); + i64 i = pMem->u.i; + sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); + if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){ + pMem->u.i = i; + MemSetTypeFlag(pMem, MEM_Int); + }else{ + MemSetTypeFlag(pMem, MEM_Real); + } } } assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); @@ -731,7 +821,7 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ } /* A no-op destructor */ -static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } +void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } /* ** Set the value stored in *pMem should already be a NULL. @@ -765,26 +855,36 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ } #endif +#ifdef SQLITE_DEBUG +/* +** Return true if the Mem holds a RowSet object. This routine is intended +** for use inside of assert() statements. +*/ +int sqlite3VdbeMemIsRowSet(const Mem *pMem){ + return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn) + && pMem->xDel==sqlite3RowSetDelete; +} +#endif + /* ** Delete any previous value and set the value of pMem to be an ** empty boolean index. +** +** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation +** error occurs. */ -void sqlite3VdbeMemSetRowSet(Mem *pMem){ +int sqlite3VdbeMemSetRowSet(Mem *pMem){ sqlite3 *db = pMem->db; + RowSet *p; assert( db!=0 ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); sqlite3VdbeMemRelease(pMem); - pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); - if( db->mallocFailed ){ - pMem->flags = MEM_Null; - pMem->szMalloc = 0; - }else{ - assert( pMem->zMalloc ); - pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); - pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); - assert( pMem->u.pRowSet!=0 ); - pMem->flags = MEM_RowSet; - } + p = sqlite3RowSetInit(db); + if( p==0 ) return SQLITE_NOMEM; + pMem->z = (char*)p; + pMem->flags = MEM_Blob|MEM_Dyn; + pMem->xDel = sqlite3RowSetDelete; + return SQLITE_OK; } /* @@ -817,7 +917,21 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ Mem *pX; for(i=0, pX=pVdbe->aMem; inMem; i++, pX++){ if( pX->pScopyFrom==pMem ){ - pX->flags |= MEM_Undefined; + /* If pX is marked as a shallow copy of pMem, then verify that + ** no significant changes have been made to pX since the OP_SCopy. + ** A significant change would indicated a missed call to this + ** function for pX. Minor changes, such as adding or removing a + ** dual type, are allowed, as long as the underlying value is the + ** same. */ + u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags; + assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i ); + assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); + assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); + assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); + + /* pMem is the register that is changing. But also mark pX as + ** undefined so that we can quickly detect the shallow-copy error */ + pX->flags = MEM_Undefined; pX->pScopyFrom = 0; } } @@ -838,7 +952,7 @@ static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){ sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); } void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ - assert( (pFrom->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); assert( pTo->db==pFrom->db ); if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } memcpy(pTo, pFrom, MEMCELLSIZE); @@ -856,7 +970,7 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc = SQLITE_OK; - assert( (pFrom->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; @@ -914,7 +1028,7 @@ int sqlite3VdbeMemSetStr( u16 flags = 0; /* New value for pMem->flags */ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ if( !z ){ @@ -931,7 +1045,7 @@ int sqlite3VdbeMemSetStr( if( nByte<0 ){ assert( enc!=0 ); if( enc==SQLITE_UTF8 ){ - nByte = sqlite3Strlen30(z); + nByte = 0x7fffffff & (int)strlen(z); if( nByte>iLimit ) nByte = iLimit+1; }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} @@ -1009,12 +1123,11 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize( ){ int rc; pMem->flags = MEM_Null; - if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){ + if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z); if( rc==SQLITE_OK ){ - pMem->z[amt] = 0; - pMem->z[amt+1] = 0; - pMem->flags = MEM_Blob|MEM_Term; + pMem->z[amt] = 0; /* Overrun area used when reading malformed records */ + pMem->flags = MEM_Blob; pMem->n = (int)amt; }else{ sqlite3VdbeMemRelease(pMem); @@ -1037,7 +1150,7 @@ int sqlite3VdbeMemFromBtree( /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); assert( zData!=0 ); @@ -1061,7 +1174,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ assert( pVal!=0 ); assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( (pVal->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); assert( (pVal->flags & (MEM_Null))==0 ); if( pVal->flags & (MEM_Blob|MEM_Str) ){ if( ExpandBlob(pVal) ) return 0; @@ -1083,6 +1196,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 || pVal->db->mallocFailed ); if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ + assert( sqlite3VdbeMemConsistentDualRep(pVal) ); return pVal->z; }else{ return 0; @@ -1103,8 +1217,9 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ if( !pVal ) return 0; assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( (pVal->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ + assert( sqlite3VdbeMemConsistentDualRep(pVal) ); return pVal->z; } if( pVal->flags&MEM_Null ){ @@ -1320,7 +1435,11 @@ static int valueFromExpr( assert( pExpr!=0 ); while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; +#if defined(SQLITE_ENABLE_STAT3_OR_STAT4) + if( op==TK_REGISTER ) op = pExpr->op2; +#else if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; +#endif /* Compressed expressions only appear when parsing the DEFAULT clause ** on a table column definition, and hence only when pCtx==0. This @@ -1404,18 +1523,25 @@ static int valueFromExpr( 0, SQLITE_DYNAMIC); } #endif - #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 else if( op==TK_FUNCTION && pCtx!=0 ){ rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); } #endif + else if( op==TK_TRUEFALSE ){ + pVal = valueNew(db, pCtx); + pVal->flags = MEM_Int; + pVal->u.i = pExpr->u.zToken[4]==0; + } *ppVal = pVal; return rc; no_mem: - sqlite3OomFault(db); +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( pCtx==0 || pCtx->pParse->nErr==0 ) +#endif + sqlite3OomFault(db); sqlite3DbFree(db, zVal); assert( *ppVal==0 ); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 @@ -1658,11 +1784,11 @@ int sqlite3Stat4Column( int iCol, /* Column to extract */ sqlite3_value **ppVal /* OUT: Extracted value */ ){ - u32 t; /* a column type code */ + u32 t = 0; /* a column type code */ int nHdr; /* Size of the header in the record */ int iHdr; /* Next unread header byte */ int iField; /* Next unread data byte */ - int szField; /* Size of the current data field */ + int szField = 0; /* Size of the current data field */ int i; /* Column index */ u8 *a = (u8*)pRec; /* Typecast byte array */ Mem *pMem = *ppVal; /* Write result into this Mem object */ diff --git a/src/vdbesort.c b/src/vdbesort.c index 8ce7415737..b30bc4e082 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1000,11 +1000,9 @@ int sqlite3VdbeSorterInit( mxCache = MIN(mxCache, SQLITE_MAX_PMASZ); pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache); - /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of - ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary - ** large heap allocations. - */ - if( sqlite3GlobalConfig.pScratch==0 ){ + /* Avoid large memory allocations if the application has requested + ** SQLITE_CONFIG_SMALL_MALLOC. */ + if( sqlite3GlobalConfig.bSmallMalloc==0 ){ assert( pSorter->iMemory==0 ); pSorter->nMemory = pgsz; pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); @@ -2109,7 +2107,11 @@ static int vdbeMergeEngineInit( ){ int rc = SQLITE_OK; /* Return code */ int i; /* For looping over PmaReader objects */ - int nTree = pMerger->nTree; + int nTree; /* Number of subtrees to merge */ + + /* Failure to allocate the merge would have been detected prior to + ** invoking this routine */ + assert( pMerger!=0 ); /* eMode is always INCRINIT_NORMAL in single-threaded mode */ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); @@ -2118,6 +2120,7 @@ static int vdbeMergeEngineInit( assert( pMerger->pTask==0 ); pMerger->pTask = pTask; + nTree = pMerger->nTree; for(i=0; i0 && eMode==INCRINIT_ROOT ){ /* PmaReaders should be normally initialized in order, as if they are diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 7b47363991..b6d9381336 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -82,7 +82,7 @@ char *sqlite3VdbeExpandSql( Mem *pVar; /* Value of a host parameter */ StrAccum out; /* Accumulate the output here */ #ifndef SQLITE_OMIT_UTF16 - Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */ + Mem utf8; /* Used to convert UTF16 into UTF8 for display */ #endif char zBase[100]; /* Initial working space */ @@ -93,17 +93,17 @@ char *sqlite3VdbeExpandSql( while( *zRawSql ){ const char *zStart = zRawSql; while( *(zRawSql++)!='\n' && *zRawSql ); - sqlite3StrAccumAppend(&out, "-- ", 3); + sqlite3_str_append(&out, "-- ", 3); assert( (zRawSql - zStart) > 0 ); - sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); + sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart)); } }else if( p->nVar==0 ){ - sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); + sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql)); }else{ while( zRawSql[0] ){ n = findNextHostParameter(zRawSql, &nToken); assert( n>0 ); - sqlite3StrAccumAppend(&out, zRawSql, n); + sqlite3_str_append(&out, zRawSql, n); zRawSql += n; assert( zRawSql[0] || nToken==0 ); if( nToken==0 ) break; @@ -129,11 +129,11 @@ char *sqlite3VdbeExpandSql( assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ - sqlite3StrAccumAppend(&out, "NULL", 4); + sqlite3_str_append(&out, "NULL", 4); }else if( pVar->flags & MEM_Int ){ - sqlite3XPrintf(&out, "%lld", pVar->u.i); + sqlite3_str_appendf(&out, "%lld", pVar->u.i); }else if( pVar->flags & MEM_Real ){ - sqlite3XPrintf(&out, "%!.15g", pVar->u.r); + sqlite3_str_appendf(&out, "%!.15g", pVar->u.r); }else if( pVar->flags & MEM_Str ){ int nOut; /* Number of bytes of the string text to include in output */ #ifndef SQLITE_OMIT_UTF16 @@ -143,7 +143,7 @@ char *sqlite3VdbeExpandSql( utf8.db = db; sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ - out.accError = STRACCUM_NOMEM; + out.accError = SQLITE_NOMEM; out.nAlloc = 0; } pVar = &utf8; @@ -156,38 +156,38 @@ char *sqlite3VdbeExpandSql( while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } } #endif - sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); + sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOutn ){ - sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif #ifndef SQLITE_OMIT_UTF16 if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); #endif }else if( pVar->flags & MEM_Zero ){ - sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); + sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero); }else{ int nOut; /* Number of bytes of the blob to include in output */ assert( pVar->flags & MEM_Blob ); - sqlite3StrAccumAppend(&out, "x'", 2); + sqlite3_str_append(&out, "x'", 2); nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; #endif for(i=0; iz[i]&0xff); + sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff); } - sqlite3StrAccumAppend(&out, "'", 1); + sqlite3_str_append(&out, "'", 1); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOutn ){ - sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif } } } - if( out.accError ) sqlite3StrAccumReset(&out); + if( out.accError ) sqlite3_str_reset(&out); return sqlite3StrAccumFinish(&out); } diff --git a/src/vtab.c b/src/vtab.c index 917c26f5fa..27317806cc 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -42,8 +42,10 @@ Module *sqlite3VtabCreateModule( ){ Module *pMod; int nName = sqlite3Strlen30(zName); - pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); - if( pMod ){ + pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); + if( pMod==0 ){ + sqlite3OomFault(db); + }else{ Module *pDel; char *zCopy = (char *)(&pMod[1]); memcpy(zCopy, zName, nName+1); @@ -260,7 +262,7 @@ void sqlite3VtabUnlockList(sqlite3 *db){ assert( sqlite3_mutex_held(db->mutex) ); if( p ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); do { VTable *pNext = p->pNext; sqlite3VtabUnlock(p); @@ -326,7 +328,6 @@ void sqlite3VtabBeginParse( Token *pModuleName, /* Name of the module for the virtual table */ int ifNotExists /* No error if the table already exists */ ){ - int iDb; /* The database the table is being created in */ Table *pTable; /* The new virtual table */ sqlite3 *db; /* Database connection */ @@ -336,8 +337,6 @@ void sqlite3VtabBeginParse( assert( 0==pTable->pIndex ); db = pParse->db; - iDb = sqlite3SchemaToIndex(db, pTable->pSchema); - assert( iDb>=0 ); assert( pTable->nModuleArg==0 ); addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); @@ -357,6 +356,8 @@ void sqlite3VtabBeginParse( ** The second call, to obtain permission to create the table, is made now. */ if( pTable->azModuleArg ){ + int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); + assert( iDb>=0 ); /* The database the table is being created in */ sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); } @@ -518,13 +519,14 @@ static int vtabCallConstructor( } } - zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); + zModuleName = sqlite3DbStrDup(db, pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM_BKPT; } - pVTable = sqlite3DbMallocZero(db, sizeof(VTable)); + pVTable = sqlite3MallocZero(sizeof(VTable)); if( !pVTable ){ + sqlite3OomFault(db); sqlite3DbFree(db, zModuleName); return SQLITE_NOMEM_BKPT; } @@ -644,6 +646,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "%s", zErr); + pParse->rc = rc; } sqlite3DbFree(db, zErr); } @@ -754,7 +757,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ assert( IsVirtual(pTab) ); memset(&sParse, 0, sizeof(sParse)); - sParse.declareVtab = 1; + sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; sParse.db = db; sParse.nQueryLoop = 1; if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) @@ -772,7 +775,13 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ pNew->nCol = 0; pNew->aCol = 0; assert( pTab->pIndex==0 ); - if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){ + assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); + if( !HasRowid(pNew) + && pCtx->pVTable->pMod->pModule->xUpdate!=0 + && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1 + ){ + /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0) + ** or else must have a single-column PRIMARY KEY */ rc = SQLITE_ERROR; } pIdx = pNew->pIndex; @@ -789,7 +798,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3DbFree(db, zErr); rc = SQLITE_ERROR; } - sParse.declareVtab = 0; + sParse.eParseMode = PARSE_MODE_NORMAL; if( sParse.pVdbe ){ sqlite3VdbeFinalize(sParse.pVdbe); @@ -1039,14 +1048,11 @@ FuncDef *sqlite3VtabOverloadFunction( void *pArg = 0; FuncDef *pNew; int rc = 0; - char *zLowerName; - unsigned char *z; - /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; - pTab = pExpr->pTab; + pTab = pExpr->y.pTab; if( pTab==0 ) return pDef; if( !IsVirtual(pTab) ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; @@ -1056,16 +1062,22 @@ FuncDef *sqlite3VtabOverloadFunction( if( pMod->xFindFunction==0 ) return pDef; /* Call the xFindFunction method on the virtual table implementation - ** to see if the implementation wants to overload this function + ** to see if the implementation wants to overload this function. + ** + ** Though undocumented, we have historically always invoked xFindFunction + ** with an all lower-case function name. Continue in this tradition to + ** avoid any chance of an incompatibility. */ - zLowerName = sqlite3DbStrDup(db, pDef->zName); - if( zLowerName ){ - for(z=(unsigned char*)zLowerName; *z; z++){ - *z = sqlite3UpperToLower[*z]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; pDef->zName[i]; i++){ + unsigned char x = (unsigned char)pDef->zName[i]; + assert( x==sqlite3UpperToLower[x] ); } - rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg); - sqlite3DbFree(db, zLowerName); } +#endif + rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg); if( rc==0 ){ return pDef; } diff --git a/src/wal.c b/src/wal.c index 09f605fe57..4088bf2ec8 100644 --- a/src/wal.c +++ b/src/wal.c @@ -132,6 +132,10 @@ ** on a network filesystem. All users of the database must be able to ** share memory. ** +** In the default unix and windows implementation, the wal-index is a mmapped +** file whose name is the database name with a "-shm" suffix added. For that +** reason, the wal-index is sometimes called the "shm" file. +** ** The wal-index is transient. After a crash, the wal-index can (and should ** be) reconstructed from the original WAL file. In fact, the VFS is required ** to either truncate or zero the header of the wal-index when the last @@ -254,6 +258,18 @@ int sqlite3WalTrace = 0; # define WALTRACE(X) #endif +/* +** WAL mode depends on atomic aligned 32-bit loads and stores in a few +** places. The following macros try to make this explicit. +*/ +#if GCC_VESRION>=5004000 +# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) +# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) +#else +# define AtomicLoad(PTR) (*(PTR)) +# define AtomicStore(PTR,VAL) (*(PTR) = (VAL)) +#endif + /* ** The maximum (and only) versions of the wal and wal-index formats ** that may be interpreted by this version of SQLite. @@ -271,9 +287,18 @@ int sqlite3WalTrace = 0; #define WALINDEX_MAX_VERSION 3007000 /* -** Indices of various locking bytes. WAL_NREADER is the number +** Index numbers for various locking bytes. WAL_NREADER is the number ** of available reader locks and should be at least 3. The default ** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. +** +** Technically, the various VFSes are free to implement these locks however +** they see fit. However, compatibility is encouraged so that VFSes can +** interoperate. The standard implemention used on both unix and windows +** is for the index number to indicate a byte offset into the +** WalCkptInfo.aLock[] array in the wal-index header. In other words, all +** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which +** should be 120) is the location in the shm file for the first locking +** byte. */ #define WAL_WRITE_LOCK 0 #define WAL_ALL_BUT_WRITE 1 @@ -397,7 +422,6 @@ struct WalCkptInfo { #define WAL_FRAME_HDRSIZE 24 /* Size of write ahead log header, including checksum. */ -/* #define WAL_HDRSIZE 24 */ #define WAL_HDRSIZE 32 /* WAL magic value. Either this value, or the same value with the least @@ -443,6 +467,7 @@ struct Wal { u8 truncateOnCommit; /* True to truncate WAL file on commit */ u8 syncHeader; /* Fsync the WAL header if true */ u8 padToSectorBoundary; /* Pad transactions out to the next sector */ + u8 bShmUnreliable; /* SHM content is read-only and unreliable */ WalIndexHdr hdr; /* Wal-index header for current transaction */ u32 minFrame; /* Ignore wal frames before this one */ u32 iReCksum; /* On commit, recalculate checksums from here */ @@ -532,11 +557,20 @@ struct WalIterator { ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are ** numbered from zero. ** +** If the wal-index is currently smaller the iPage pages then the size +** of the wal-index might be increased, but only if it is safe to do +** so. It is safe to enlarge the wal-index if pWal->writeLock is true +** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE. +** ** If this call is successful, *ppPage is set to point to the wal-index ** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs, ** then an SQLite error code is returned and *ppPage is set to 0. */ -static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ +static SQLITE_NOINLINE int walIndexPageRealloc( + Wal *pWal, /* The WAL context */ + int iPage, /* The page we seek */ + volatile u32 **ppPage /* Write the page pointer here */ +){ int rc = SQLITE_OK; /* Enlarge the pWal->apWiData[] array if required */ @@ -555,16 +589,19 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ } /* Request a pointer to the required page from the VFS */ - if( pWal->apWiData[iPage]==0 ){ - if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ - pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); - if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; - }else{ - rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, - pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] - ); + assert( pWal->apWiData[iPage]==0 ); + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); + if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] + ); + assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 ); + testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK ); + if( (rc&0xff)==SQLITE_READONLY ){ + pWal->readOnly |= WAL_SHM_RDONLY; if( rc==SQLITE_READONLY ){ - pWal->readOnly |= WAL_SHM_RDONLY; rc = SQLITE_OK; } } @@ -574,6 +611,16 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); return rc; } +static int walIndexPage( + Wal *pWal, /* The WAL context */ + int iPage, /* The page we seek */ + volatile u32 **ppPage /* Write the page pointer here */ +){ + if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ + return walIndexPageRealloc(pWal, iPage, ppPage); + } + return SQLITE_OK; +} /* ** Return a pointer to the WalCkptInfo structure in the wal-index. @@ -845,48 +892,51 @@ static int walNextHash(int iPriorHash){ return (iPriorHash+1)&(HASHTABLE_NSLOT-1); } +/* +** An instance of the WalHashLoc object is used to describe the location +** of a page hash table in the wal-index. This becomes the return value +** from walHashGet(). +*/ +typedef struct WalHashLoc WalHashLoc; +struct WalHashLoc { + volatile ht_slot *aHash; /* Start of the wal-index hash table */ + volatile u32 *aPgno; /* aPgno[1] is the page of first frame indexed */ + u32 iZero; /* One less than the frame number of first indexed*/ +}; + /* ** Return pointers to the hash table and page number array stored on ** page iHash of the wal-index. The wal-index is broken into 32KB pages ** numbered starting from 0. ** -** Set output variable *paHash to point to the start of the hash table -** in the wal-index file. Set *piZero to one less than the frame +** Set output variable pLoc->aHash to point to the start of the hash table +** in the wal-index file. Set pLoc->iZero to one less than the frame ** number of the first frame indexed by this hash table. If a ** slot in the hash table is set to N, it refers to frame number -** (*piZero+N) in the log. +** (pLoc->iZero+N) in the log. ** -** Finally, set *paPgno so that *paPgno[1] is the page number of the -** first frame indexed by the hash table, frame (*piZero+1). +** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the +** first frame indexed by the hash table, frame (pLoc->iZero+1). */ static int walHashGet( Wal *pWal, /* WAL handle */ int iHash, /* Find the iHash'th table */ - volatile ht_slot **paHash, /* OUT: Pointer to hash index */ - volatile u32 **paPgno, /* OUT: Pointer to page number array */ - u32 *piZero /* OUT: Frame associated with *paPgno[0] */ + WalHashLoc *pLoc /* OUT: Hash table location */ ){ int rc; /* Return code */ - volatile u32 *aPgno; - rc = walIndexPage(pWal, iHash, &aPgno); + rc = walIndexPage(pWal, iHash, &pLoc->aPgno); assert( rc==SQLITE_OK || iHash>0 ); if( rc==SQLITE_OK ){ - u32 iZero; - volatile ht_slot *aHash; - - aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE]; + pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE]; if( iHash==0 ){ - aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; - iZero = 0; + pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; + pLoc->iZero = 0; }else{ - iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; + pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; } - - *paPgno = &aPgno[-1]; - *paHash = aHash; - *piZero = iZero; + pLoc->aPgno = &pLoc->aPgno[-1]; } return rc; } @@ -932,9 +982,7 @@ static u32 walFramePgno(Wal *pWal, u32 iFrame){ ** actually needed. */ static void walCleanupHash(Wal *pWal){ - volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ - volatile u32 *aPgno = 0; /* Page number array for hash table */ - u32 iZero = 0; /* frame == (aHash[x]+iZero) */ + WalHashLoc sLoc; /* Hash table location */ int iLimit = 0; /* Zero values greater than this */ int nByte; /* Number of bytes to zero in aPgno[] */ int i; /* Used to iterate through aHash[] */ @@ -952,24 +1000,24 @@ static void walCleanupHash(Wal *pWal){ */ assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); - walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero); + walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc); /* Zero all hash-table entries that correspond to frame numbers greater ** than pWal->hdr.mxFrame. */ - iLimit = pWal->hdr.mxFrame - iZero; + iLimit = pWal->hdr.mxFrame - sLoc.iZero; assert( iLimit>0 ); for(i=0; iiLimit ){ - aHash[i] = 0; + if( sLoc.aHash[i]>iLimit ){ + sLoc.aHash[i] = 0; } } /* Zero the entries in the aPgno array that correspond to frames with ** frame numbers greater than pWal->hdr.mxFrame. */ - nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); - memset((void *)&aPgno[iLimit+1], 0, nByte); + nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]); + memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte); #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT /* Verify that the every entry in the mapping region is still reachable @@ -979,10 +1027,10 @@ static void walCleanupHash(Wal *pWal){ int j; /* Loop counter */ int iKey; /* Hash key */ for(j=1; j<=iLimit; j++){ - for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){ - if( aHash[iKey]==j ) break; + for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){ + if( sLoc.aHash[iKey]==j ) break; } - assert( aHash[iKey]==j ); + assert( sLoc.aHash[iKey]==j ); } } #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ @@ -995,11 +1043,9 @@ static void walCleanupHash(Wal *pWal){ */ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ int rc; /* Return code */ - u32 iZero = 0; /* One less than frame number of aPgno[1] */ - volatile u32 *aPgno = 0; /* Page number array */ - volatile ht_slot *aHash = 0; /* Hash table */ + WalHashLoc sLoc; /* Wal-index hash table location */ - rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); + rc = walHashGet(pWal, walFramePage(iFrame), &sLoc); /* Assuming the wal-index file was successfully mapped, populate the ** page number array and hash table entry. @@ -1009,15 +1055,16 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ int idx; /* Value to write to hash-table slot */ int nCollide; /* Number of hash collisions */ - idx = iFrame - iZero; + idx = iFrame - sLoc.iZero; assert( idx <= HASHTABLE_NSLOT/2 + 1 ); /* If this is the first entry to be added to this hash-table, zero the ** entire hash table and aPgno[] array before proceeding. */ if( idx==1 ){ - int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); - memset((void*)&aPgno[1], 0, nByte); + int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT] + - (u8 *)&sLoc.aPgno[1]); + memset((void*)&sLoc.aPgno[1], 0, nByte); } /* If the entry in aPgno[] is already set, then the previous writer @@ -1026,18 +1073,18 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ ** Remove the remnants of that writers uncommitted transaction from ** the hash-table before writing any new entries. */ - if( aPgno[idx] ){ + if( sLoc.aPgno[idx] ){ walCleanupHash(pWal); - assert( !aPgno[idx] ); + assert( !sLoc.aPgno[idx] ); } /* Write the aPgno[] array entry and the hash-table slot. */ nCollide = idx; - for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ + for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; } - aPgno[idx] = iPage; - aHash[iKey] = (ht_slot)idx; + sLoc.aPgno[idx] = iPage; + sLoc.aHash[iKey] = (ht_slot)idx; #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT /* Verify that the number of entries in the hash table exactly equals @@ -1046,7 +1093,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ { int i; /* Loop counter */ int nEntry = 0; /* Number of entries in the hash table */ - for(i=0; iwriteLock ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; - nLock = SQLITE_SHM_NLOCK - iLock; - rc = walLockExclusive(pWal, iLock, nLock); + rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); + if( rc==SQLITE_OK ){ + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc!=SQLITE_OK ){ + walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); + } + } if( rc ){ return rc; } + WALTRACE(("WAL%p: recovery begin...\n", pWal)); memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); @@ -1242,7 +1296,8 @@ finished: recovery_error: WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); - walUnlockExclusive(pWal, iLock, nLock); + walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); return rc; } @@ -1250,13 +1305,14 @@ recovery_error: ** Close an open wal-index. */ static void walIndexClose(Wal *pWal, int isDelete){ - if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){ int i; for(i=0; inWiData; i++){ sqlite3_free((void *)pWal->apWiData[i]); pWal->apWiData[i] = 0; } - }else{ + } + if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ sqlite3OsShmUnmap(pWal->pDbFd, isDelete); } } @@ -1543,8 +1599,9 @@ static void walIteratorFree(WalIterator *p){ /* ** Construct a WalInterator object that can be used to loop over all -** pages in the WAL in ascending order. The caller must hold the checkpoint -** lock. +** pages in the WAL following frame nBackfill in ascending order. Frames +** nBackfill or earlier may be included - excluding them is an optimization +** only. The caller must hold the checkpoint lock. ** ** On success, make *pp point to the newly allocated WalInterator object ** return SQLITE_OK. Otherwise, return an error code. If this routine @@ -1553,7 +1610,7 @@ static void walIteratorFree(WalIterator *p){ ** The calling routine should invoke walIteratorFree() to destroy the ** WalIterator object when it has finished with it. */ -static int walIteratorInit(Wal *pWal, WalIterator **pp){ +static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ WalIterator *p; /* Return value */ int nSegment; /* Number of segments to merge */ u32 iLast; /* Last frame in log */ @@ -1590,40 +1647,39 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){ rc = SQLITE_NOMEM_BKPT; } - for(i=0; rc==SQLITE_OK && iaSegment[p->nSegment])[iZero]; - iZero++; + aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero]; + sLoc.iZero++; for(j=0; jaSegment[i].iZero = iZero; + walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry); + p->aSegment[i].iZero = sLoc.iZero; p->aSegment[i].nEntry = nEntry; p->aSegment[i].aIndex = aIndex; - p->aSegment[i].aPgno = (u32 *)aPgno; + p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; } } sqlite3_free(aTmp); if( rc!=SQLITE_OK ){ walIteratorFree(p); + p = 0; } *pp = p; return rc; @@ -1746,13 +1802,6 @@ static int walCheckpoint( pInfo = walCkptInfo(pWal); if( pInfo->nBackfillhdr.mxFrame ){ - /* Allocate the iterator */ - rc = walIteratorInit(pWal, &pIter); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pIter ); - /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); @@ -1789,24 +1838,28 @@ static int walCheckpoint( } } - if( pInfo->nBackfillnBackfillnBackfill, &pIter); + assert( rc==SQLITE_OK || pIter==0 ); + } + + if( pIter && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK ){ - i64 nSize; /* Current size of database file */ u32 nBackfill = pInfo->nBackfill; pInfo->nBackfillAttempted = mxSafeFrame; /* Sync the WAL to disk */ - if( sync_flags ){ - rc = sqlite3OsSync(pWal->pWalFd, sync_flags); - } + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); /* If the database may grow as a result of this checkpoint, hint ** about the eventual size of the db file to the VFS layer. */ if( rc==SQLITE_OK ){ i64 nReq = ((i64)mxPage * szPage); + i64 nSize; /* Current size of database file */ rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); if( rc==SQLITE_OK && nSizepDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); @@ -1841,8 +1894,8 @@ static int walCheckpoint( i64 szDb = pWal->hdr.nPage*(i64)szPage; testcase( IS_BIG_INT(szDb) ); rc = sqlite3OsTruncate(pWal->pDbFd, szDb); - if( rc==SQLITE_OK && sync_flags ){ - rc = sqlite3OsSync(pWal->pDbFd, sync_flags); + if( rc==SQLITE_OK ){ + rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); } } if( rc==SQLITE_OK ){ @@ -2051,6 +2104,12 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){ return 0; } +/* +** This is the value that walTryBeginRead returns when it needs to +** be retried. +*/ +#define WAL_RETRY (-1) + /* ** Read the wal-index header from the wal-index and into pWal->hdr. ** If the wal-header appears to be corrupt, try to reconstruct the @@ -2074,9 +2133,29 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ assert( pChanged ); rc = walIndexPage(pWal, 0, &page0); if( rc!=SQLITE_OK ){ - return rc; - }; - assert( page0 || pWal->writeLock==0 ); + assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */ + if( rc==SQLITE_READONLY_CANTINIT ){ + /* The SQLITE_READONLY_CANTINIT return means that the shared-memory + ** was openable but is not writable, and this thread is unable to + ** confirm that another write-capable connection has the shared-memory + ** open, and hence the content of the shared-memory is unreliable, + ** since the shared-memory might be inconsistent with the WAL file + ** and there is no writer on hand to fix it. */ + assert( page0==0 ); + assert( pWal->writeLock==0 ); + assert( pWal->readOnly & WAL_SHM_RDONLY ); + pWal->bShmUnreliable = 1; + pWal->exclusiveMode = WAL_HEAPMEMORY_MODE; + *pChanged = 1; + }else{ + return rc; /* Any other non-OK return is just an error */ + } + }else{ + /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock + ** is zero, which prevents the SHM from growing */ + testcase( page0!=0 ); + } + assert( page0!=0 || pWal->writeLock==0 ); /* If the first page of the wal-index has been mapped, try to read the ** wal-index header immediately, without holding any lock. This usually @@ -2090,7 +2169,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ */ assert( badHdr==0 || pWal->writeLock==0 ); if( badHdr ){ - if( pWal->readOnly & WAL_SHM_RDONLY ){ + if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){ if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; @@ -2120,15 +2199,193 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ rc = SQLITE_CANTOPEN_BKPT; } + if( pWal->bShmUnreliable ){ + if( rc!=SQLITE_OK ){ + walIndexClose(pWal, 0); + pWal->bShmUnreliable = 0; + assert( pWal->nWiData>0 && pWal->apWiData[0]==0 ); + /* walIndexRecover() might have returned SHORT_READ if a concurrent + ** writer truncated the WAL out from under it. If that happens, it + ** indicates that a writer has fixed the SHM file for us, so retry */ + if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY; + } + pWal->exclusiveMode = WAL_NORMAL_MODE; + } return rc; } /* -** This is the value that walTryBeginRead returns when it needs to -** be retried. +** Open a transaction in a connection where the shared-memory is read-only +** and where we cannot verify that there is a separate write-capable connection +** on hand to keep the shared-memory up-to-date with the WAL file. +** +** This can happen, for example, when the shared-memory is implemented by +** memory-mapping a *-shm file, where a prior writer has shut down and +** left the *-shm file on disk, and now the present connection is trying +** to use that database but lacks write permission on the *-shm file. +** Other scenarios are also possible, depending on the VFS implementation. +** +** Precondition: +** +** The *-wal file has been read and an appropriate wal-index has been +** constructed in pWal->apWiData[] using heap memory instead of shared +** memory. +** +** If this function returns SQLITE_OK, then the read transaction has +** been successfully opened. In this case output variable (*pChanged) +** is set to true before returning if the caller should discard the +** contents of the page cache before proceeding. Or, if it returns +** WAL_RETRY, then the heap memory wal-index has been discarded and +** the caller should retry opening the read transaction from the +** beginning (including attempting to map the *-shm file). +** +** If an error occurs, an SQLite error code is returned. */ -#define WAL_RETRY (-1) +static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ + i64 szWal; /* Size of wal file on disk in bytes */ + i64 iOffset; /* Current offset when reading wal file */ + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ + int szFrame; /* Number of bytes in buffer aFrame[] */ + u8 *aData; /* Pointer to data part of aFrame buffer */ + volatile void *pDummy; /* Dummy argument for xShmMap */ + int rc; /* Return code */ + u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */ + + assert( pWal->bShmUnreliable ); + assert( pWal->readOnly & WAL_SHM_RDONLY ); + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + + /* Take WAL_READ_LOCK(0). This has the effect of preventing any + ** writers from running a checkpoint, but does not stop them + ** from running recovery. */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_BUSY ) rc = WAL_RETRY; + goto begin_unreliable_shm_out; + } + pWal->readLock = 0; + + /* Check to see if a separate writer has attached to the shared-memory area, + ** thus making the shared-memory "reliable" again. Do this by invoking + ** the xShmMap() routine of the VFS and looking to see if the return + ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT. + ** + ** If the shared-memory is now "reliable" return WAL_RETRY, which will + ** cause the heap-memory WAL-index to be discarded and the actual + ** shared memory to be used in its place. + ** + ** This step is important because, even though this connection is holding + ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might + ** have already checkpointed the WAL file and, while the current + ** is active, wrap the WAL and start overwriting frames that this + ** process wants to use. + ** + ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has + ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY + ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations, + ** even if some external agent does a "chmod" to make the shared-memory + ** writable by us, until sqlite3OsShmUnmap() has been called. + ** This is a requirement on the VFS implementation. + */ + rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy); + assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */ + if( rc!=SQLITE_READONLY_CANTINIT ){ + rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); + goto begin_unreliable_shm_out; + } + + /* We reach this point only if the real shared-memory is still unreliable. + ** Assume the in-memory WAL-index substitute is correct and load it + ** into pWal->hdr. + */ + memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + /* Make sure some writer hasn't come in and changed the WAL file out + ** from under us, then disconnected, while we were not looking. + */ + rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); + if( rc!=SQLITE_OK ){ + goto begin_unreliable_shm_out; + } + if( szWalhdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY); + goto begin_unreliable_shm_out; + } + + /* Check the salt keys at the start of the wal file still match. */ + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + if( rc!=SQLITE_OK ){ + goto begin_unreliable_shm_out; + } + if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){ + /* Some writer has wrapped the WAL file while we were not looking. + ** Return WAL_RETRY which will cause the in-memory WAL-index to be + ** rebuilt. */ + rc = WAL_RETRY; + goto begin_unreliable_shm_out; + } + + /* Allocate a buffer to read frames into */ + szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc64(szFrame); + if( aFrame==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto begin_unreliable_shm_out; + } + aData = &aFrame[WAL_FRAME_HDRSIZE]; + + /* Check to see if a complete transaction has been appended to the + ** wal file since the heap-memory wal-index was created. If so, the + ** heap-memory wal-index is discarded and WAL_RETRY returned to + ** the caller. */ + aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; + aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; + for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage); + iOffset+szFrame<=szWal; + iOffset+=szFrame + ){ + u32 pgno; /* Database page number for frame */ + u32 nTruncate; /* dbsize field from frame header */ + + /* Read and decode the next log frame. */ + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + if( rc!=SQLITE_OK ) break; + if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break; + + /* If nTruncate is non-zero, then a complete transaction has been + ** appended to this wal file. Set rc to WAL_RETRY and break out of + ** the loop. */ + if( nTruncate ){ + rc = WAL_RETRY; + break; + } + } + pWal->hdr.aFrameCksum[0] = aSaveCksum[0]; + pWal->hdr.aFrameCksum[1] = aSaveCksum[1]; + + begin_unreliable_shm_out: + sqlite3_free(aFrame); + if( rc!=SQLITE_OK ){ + int i; + for(i=0; inWiData; i++){ + sqlite3_free((void*)pWal->apWiData[i]); + pWal->apWiData[i] = 0; + } + pWal->bShmUnreliable = 0; + sqlite3WalEndReadTransaction(pWal); + *pChanged = 1; + } + return rc; +} /* ** Attempt to start a read transaction. This might fail due to a race or @@ -2144,7 +2401,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ ** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() ** to make a copy of the wal-index header into pWal->hdr. If the ** wal-index header has changed, *pChanged is set to 1 (as an indication -** to the caller that the local paget cache is obsolete and needs to be +** to the caller that the local page cache is obsolete and needs to be ** flushed.) When useWal==1, the wal-index header is assumed to already ** be loaded and the pChanged parameter is unused. ** @@ -2190,6 +2447,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ assert( pWal->readLock<0 ); /* Not currently locked */ + /* useWal may only be set for read/write connections */ + assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 ); + /* Take steps to avoid spinning forever if there is a protocol error. ** ** Circumstances that cause a RETRY should only last for the briefest @@ -2218,7 +2478,10 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } if( !useWal ){ - rc = walIndexReadHdr(pWal, pChanged); + assert( rc==SQLITE_OK ); + if( pWal->bShmUnreliable==0 ){ + rc = walIndexReadHdr(pWal, pChanged); + } if( rc==SQLITE_BUSY ){ /* If there is not a recovery running in another thread or process ** then convert BUSY errors to WAL_RETRY. If recovery is known to @@ -2247,13 +2510,17 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ if( rc!=SQLITE_OK ){ return rc; } + else if( pWal->bShmUnreliable ){ + return walBeginShmUnreliable(pWal, pChanged); + } } + assert( pWal->nWiData>0 ); + assert( pWal->apWiData[0]!=0 ); pInfo = walCkptInfo(pWal); - if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame + if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0 - || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr))) + && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) #endif ){ /* The WAL has been completely backfilled (or it is empty). @@ -2300,7 +2567,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } #endif for(i=1; iaReadMark[i]; + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); if( mxReadMark<=thisMark && thisMark<=mxFrame ){ assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; @@ -2313,7 +2580,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ for(i=1; iaReadMark[i] = mxFrame; + mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame); mxI = i; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); break; @@ -2324,7 +2591,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } if( mxI==0 ){ assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); - return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; } rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); @@ -2365,9 +2632,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** we can guarantee that the checkpointer that set nBackfill could not ** see any pages past pWal->hdr.mxFrame, this problem does not come up. */ - pWal->minFrame = pInfo->nBackfill+1; + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; walShmBarrier(pWal); - if( pInfo->aReadMark[mxI]!=mxReadMark + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ walUnlockShared(pWal, WAL_READ_LOCK(mxI)); @@ -2418,16 +2685,14 @@ int sqlite3WalSnapshotRecover(Wal *pWal){ }else{ u32 i = pInfo->nBackfillAttempted; for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ - volatile ht_slot *dummy; - volatile u32 *aPgno; /* Array of page numbers */ - u32 iZero; /* Frame corresponding to aPgno[0] */ + WalHashLoc sLoc; /* Hash table location */ u32 pgno; /* Page number in db file */ i64 iDbOff; /* Offset of db file entry */ i64 iWalOff; /* Offset of wal file entry */ - rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); + rc = walHashGet(pWal, walFramePage(i), &sLoc); if( rc!=SQLITE_OK ) break; - pgno = aPgno[i-iZero]; + pgno = sLoc.aPgno[i-sLoc.iZero]; iDbOff = (i64)(pgno-1) * szPage; if( iDbOff+szPage<=szDb ){ @@ -2468,7 +2733,7 @@ int sqlite3WalSnapshotRecover(Wal *pWal){ ** ** If the database contents have changes since the previous read ** transaction, then *pChanged is set to 1 before returning. The -** Pager layer will use this to know that is cache is stale and +** Pager layer will use this to know that its cache is stale and ** needs to be flushed. */ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ @@ -2530,7 +2795,7 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ /* Check that the wal file has not been wrapped. Assuming that it has ** not, also check that no checkpointer has attempted to checkpoint any ** frames beyond pSnapshot->mxFrame. If either of these conditions are - ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr + ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr ** with *pSnapshot and set *pChanged as appropriate for opening the ** snapshot. */ if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) @@ -2540,11 +2805,12 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr)); *pChanged = bChanged; }else{ - rc = SQLITE_BUSY_SNAPSHOT; + rc = SQLITE_ERROR_SNAPSHOT; } /* Release the shared CKPT lock obtained above. */ walUnlockShared(pWal, WAL_CKPT_LOCK); + pWal->minFrame = 1; } @@ -2596,7 +2862,7 @@ int sqlite3WalFindFrame( ** then the WAL is ignored by the reader so return early, as if the ** WAL were empty. */ - if( iLast==0 || pWal->readLock==0 ){ + if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){ *piRead = 0; return SQLITE_OK; } @@ -2627,22 +2893,21 @@ int sqlite3WalFindFrame( ** table after the current read-transaction had started. */ iMinHash = walFramePage(pWal->minFrame); - for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){ - volatile ht_slot *aHash; /* Pointer to hash table */ - volatile u32 *aPgno; /* Pointer to array of page numbers */ - u32 iZero; /* Frame number corresponding to aPgno[0] */ + for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){ + WalHashLoc sLoc; /* Hash table location */ int iKey; /* Hash slot index */ int nCollide; /* Number of hash collisions remaining */ int rc; /* Error code */ - rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); + rc = walHashGet(pWal, iHash, &sLoc); if( rc!=SQLITE_OK ){ return rc; } nCollide = HASHTABLE_NSLOT; - for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ - u32 iFrame = aHash[iKey] + iZero; - if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){ + for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ + u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero; + if( iFrame<=iLast && iFrame>=pWal->minFrame + && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){ assert( iFrame>iRead || CORRUPT_DB ); iRead = iFrame; } @@ -2650,6 +2915,7 @@ int sqlite3WalFindFrame( return SQLITE_CORRUPT_BKPT; } } + if( iRead ) break; } #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT @@ -2659,8 +2925,8 @@ int sqlite3WalFindFrame( { u32 iRead2 = 0; u32 iTest; - assert( pWal->minFrame>0 ); - for(iTest=iLast; iTest>=pWal->minFrame; iTest--){ + assert( pWal->bShmUnreliable || pWal->minFrame>0 ); + for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){ if( walFramePgno(pWal, iTest)==pgno ){ iRead2 = iTest; break; @@ -2948,8 +3214,8 @@ static int walWriteToLog( iOffset += iFirstAmt; iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); - assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); - rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK); + assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); + rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); if( iAmt==0 || rc ) return rc; } rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); @@ -3119,10 +3385,10 @@ int sqlite3WalFrames( ** an out-of-order write following a WAL restart could result in ** database corruption. See the ticket: ** - ** http://localhost:591/sqlite/info/ff5be73dee + ** https://sqlite.org/src/info/ff5be73dee */ - if( pWal->syncHeader && sync_flags ){ - rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); + if( pWal->syncHeader ){ + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); if( rc ) return rc; } } @@ -3197,7 +3463,7 @@ int sqlite3WalFrames( ** sector boundary is synced; the part of the last frame that extends ** past the sector boundary is written after the sync. */ - if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ + if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ int bSync = 1; if( pWal->padToSectorBoundary ){ int sectorSize = sqlite3SectorSize(pWal->pWalFd); @@ -3213,7 +3479,7 @@ int sqlite3WalFrames( } if( bSync ){ assert( rc==SQLITE_OK ); - rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); + rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags)); } } @@ -3436,24 +3702,24 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op){ assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); if( op==0 ){ - if( pWal->exclusiveMode ){ - pWal->exclusiveMode = 0; + if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){ + pWal->exclusiveMode = WAL_NORMAL_MODE; if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ - pWal->exclusiveMode = 1; + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } - rc = pWal->exclusiveMode==0; + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; }else{ /* Already in locking_mode=NORMAL */ rc = 0; } }else if( op>0 ){ - assert( pWal->exclusiveMode==0 ); + assert( pWal->exclusiveMode==WAL_NORMAL_MODE ); assert( pWal->readLock>=0 ); walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); - pWal->exclusiveMode = 1; + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; rc = 1; }else{ - rc = pWal->exclusiveMode==0; + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; } return rc; } @@ -3516,6 +3782,43 @@ int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; return 0; } + +/* +** The caller currently has a read transaction open on the database. +** This function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ + int rc; + rc = walLockShared(pWal, WAL_CKPT_LOCK); + if( rc==SQLITE_OK ){ + WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; + if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + || pNew->mxFramenBackfillAttempted + ){ + rc = SQLITE_ERROR_SNAPSHOT; + walUnlockShared(pWal, WAL_CKPT_LOCK); + } + } + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3WalSnapshotCheck(). +*/ +void sqlite3WalSnapshotUnlock(Wal *pWal){ + assert( pWal ); + walUnlockShared(pWal, WAL_CKPT_LOCK); +} + + #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_ZIPVFS diff --git a/src/wal.h b/src/wal.h index 4f6d01dad6..1610607481 100644 --- a/src/wal.h +++ b/src/wal.h @@ -19,11 +19,11 @@ #include "sqliteInt.h" -/* Additional values that can be added to the sync_flags argument of -** sqlite3WalFrames(): +/* Macros for extracting appropriate sync flags for either transaction +** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): */ -#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ -#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ +#define WAL_SYNC_FLAGS(X) ((X)&0x03) +#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 @@ -132,6 +132,8 @@ int sqlite3WalHeapMemory(Wal *pWal); int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); int sqlite3WalSnapshotRecover(Wal *pWal); +int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot); +void sqlite3WalSnapshotUnlock(Wal *pWal); #endif #ifdef SQLITE_ENABLE_ZIPVFS diff --git a/src/walker.c b/src/walker.c index 2e292295de..c31d94f0bf 100644 --- a/src/walker.c +++ b/src/walker.c @@ -40,18 +40,30 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ int rc; testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_Reduced) ); - rc = pWalker->xExprCallback(pWalker, pExpr); - if( rc ) return rc & WRC_Abort; - if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ - if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; - assert( pExpr->x.pList==0 || pExpr->pRight==0 ); - if( pExpr->pRight ){ - if( walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; - }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; - }else if( pExpr->x.pList ){ - if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + while(1){ + rc = pWalker->xExprCallback(pWalker, pExpr); + if( rc ) return rc & WRC_Abort; + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; + assert( pExpr->x.pList==0 || pExpr->pRight==0 ); + if( pExpr->pRight ){ + pExpr = pExpr->pRight; + continue; + }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; + }else if( pExpr->x.pList ){ + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + Window *pWin = pExpr->y.pWin; + if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort; + } +#endif } + break; } return WRC_Continue; } @@ -87,7 +99,6 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort; return WRC_Continue; } @@ -104,16 +115,15 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ struct SrcList_item *pItem; pSrc = p->pSrc; - if( ALWAYS(pSrc) ){ - for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ - return WRC_Abort; - } - if( pItem->fg.isTabFunc - && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) - ){ - return WRC_Abort; - } + assert( pSrc!=0 ); + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ + return WRC_Abort; + } + if( pItem->fg.isTabFunc + && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) + ){ + return WRC_Abort; } } return WRC_Continue; diff --git a/src/where.c b/src/where.c index 0e82e471f4..bfc11eec18 100644 --- a/src/where.c +++ b/src/where.c @@ -19,6 +19,21 @@ #include "sqliteInt.h" #include "whereInt.h" +/* +** Extra information appended to the end of sqlite3_index_info but not +** visible to the xBestIndex function, at least not directly. The +** sqlite3_vtab_collation() interface knows how to reach it, however. +** +** This object is not an API and can be changed from one release to the +** next. As long as allocateIndexInfo() and sqlite3_vtab_collation() +** agree on the structure, all will be well. +*/ +typedef struct HiddenIndexInfo HiddenIndexInfo; +struct HiddenIndexInfo { + WhereClause *pWC; /* The Where clause being analyzed */ + Parse *pParse; /* The parsing context */ +}; + /* Forward declaration of methods */ static int whereLoopResize(sqlite3*, WhereLoop*, int); @@ -52,15 +67,38 @@ int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ } /* -** Return TRUE if the innermost loop of the WHERE clause implementation -** returns rows in ORDER BY order for complete run of the inner loop. +** In the ORDER BY LIMIT optimization, if the inner-most loop is known +** to emit rows in increasing order, and if the last row emitted by the +** inner-most loop did not fit within the sorter, then we can skip all +** subsequent rows for the current iteration of the inner loop (because they +** will not fit in the sorter either) and continue with the second inner +** loop - the loop immediately outside the inner-most. ** -** Across multiple iterations of outer loops, the output rows need not be -** sorted. As long as rows are sorted for just the innermost loop, this -** routine can return TRUE. +** When a row does not fit in the sorter (because the sorter already +** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the +** label returned by this function. +** +** If the ORDER BY LIMIT optimization applies, the jump destination should +** be the continuation for the second-inner-most loop. If the ORDER BY +** LIMIT optimization does not apply, then the jump destination should +** be the continuation for the inner-most loop. +** +** It is always safe for this routine to return the continuation of the +** inner-most loop, in the sense that a correct answer will result. +** Returning the continuation the second inner loop is an optimization +** that might make the code run a little faster, but should not change +** the final answer. */ -int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){ - return pWInfo->bOrderedInnerLoop; +int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ + WhereLevel *pInner; + if( !pWInfo->bOrderedInnerLoop ){ + /* The ORDER BY LIMIT optimization does not apply. Jump to the + ** continuation of the inner-most loop. */ + return pWInfo->iContinue; + } + pInner = &pWInfo->a[pWInfo->nLevel-1]; + assert( pInner->addrNxt!=0 ); + return pInner->addrNxt; } /* @@ -403,8 +441,8 @@ static int findIndexCol( && p->iColumn==pIdx->aiColumn[iCol] && p->iTable==iBase ){ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); - if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr); + if( 0==sqlite3StrICmp(pColl->zName, zColl) ){ return i; } } @@ -787,7 +825,6 @@ static void constructAutomaticIndex( VdbeComment((v, "for %s", pTable->zName)); /* Fill the automatic index with content */ - sqlite3ExprCachePush(pParse); pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; @@ -795,7 +832,7 @@ static void constructAutomaticIndex( 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)); + VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); }else{ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } @@ -824,7 +861,6 @@ static void constructAutomaticIndex( sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); - sqlite3ExprCachePop(pParse); /* Jump here when skipping the initialization */ sqlite3VdbeJumpHere(v, addrInit); @@ -841,11 +877,11 @@ end_auto_index_create: ** by passing the pointer returned by this function to sqlite3_free(). */ static sqlite3_index_info *allocateIndexInfo( - Parse *pParse, - WhereClause *pWC, + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause being analyzed */ Bitmask mUnusable, /* Ignore terms with these prereqs */ - struct SrcList_item *pSrc, - ExprList *pOrderBy, + struct SrcList_item *pSrc, /* The FROM clause term that is the vtab */ + ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ int i, j; @@ -853,6 +889,7 @@ static sqlite3_index_info *allocateIndexInfo( struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_orderby *pIdxOrderBy; struct sqlite3_index_constraint_usage *pUsage; + struct HiddenIndexInfo *pHidden; WhereTerm *pTerm; int nOrderBy; sqlite3_index_info *pIdxInfo; @@ -868,7 +905,7 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IS ); testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; + if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; assert( pTerm->u.leftColumn>=(-1) ); nTerm++; @@ -894,7 +931,7 @@ static sqlite3_index_info *allocateIndexInfo( */ pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm - + sizeof(*pIdxOrderBy)*nOrderBy ); + + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) ); if( pIdxInfo==0 ){ sqlite3ErrorMsg(pParse, "out of memory"); return 0; @@ -905,7 +942,8 @@ static sqlite3_index_info *allocateIndexInfo( ** changing them. We have to do some funky casting in order to ** initialize those fields. */ - pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1]; + pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; + pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; *(int*)&pIdxInfo->nConstraint = nTerm; @@ -915,8 +953,10 @@ static sqlite3_index_info *allocateIndexInfo( *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = pUsage; + pHidden->pWC = pWC; + pHidden->pParse = pParse; for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - u8 op; + u16 op; if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->prereqRight & mUnusable ) continue; assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); @@ -924,34 +964,54 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator & WO_IS ); testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; + if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; + if( (pSrc->fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + && (pTerm->eOperator & (WO_IS|WO_ISNULL)) + ){ + /* An "IS" term in the WHERE clause where the virtual table is the rhs + ** of a LEFT JOIN. Do not pass this term to the virtual table + ** implementation, as this can lead to incorrect results from SQL such + ** as: + ** + ** "LEFT JOIN vtab WHERE vtab.col IS NULL" */ + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IS ); + continue; + } assert( pTerm->u.leftColumn>=(-1) ); pIdxCons[j].iColumn = pTerm->u.leftColumn; pIdxCons[j].iTermOffset = i; - op = (u8)pTerm->eOperator & WO_ALL; + op = pTerm->eOperator & WO_ALL; if( op==WO_IN ) op = WO_EQ; - if( op==WO_MATCH ){ - op = pTerm->eMatchOp; - } - pIdxCons[j].op = op; - /* The direct assignment in the previous line is possible only because - ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The - ** following asserts verify this fact. */ - assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); - assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); - assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); - assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); - assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); - assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); - assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); + if( op==WO_AUX ){ + pIdxCons[j].op = pTerm->eMatchOp; + }else if( op & (WO_ISNULL|WO_IS) ){ + if( op==WO_ISNULL ){ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; + }else{ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; + } + }else{ + pIdxCons[j].op = (u8)op; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); - if( op & (WO_LT|WO_LE|WO_GT|WO_GE) - && sqlite3ExprIsVector(pTerm->pExpr->pRight) - ){ - if( i<16 ) mNoOmit |= (1 << i); - if( op==WO_LT ) pIdxCons[j].op = WO_LE; - if( op==WO_GT ) pIdxCons[j].op = WO_GE; + if( op & (WO_LT|WO_LE|WO_GT|WO_GE) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) + ){ + if( i<16 ) mNoOmit |= (1 << i); + if( op==WO_LT ) pIdxCons[j].op = WO_LE; + if( op==WO_GT ) pIdxCons[j].op = WO_GE; + } } j++; @@ -1411,7 +1471,9 @@ static int whereRangeScanEst( Index *p = pLoop->u.btree.pIndex; int nEq = pLoop->u.btree.nEq; - if( p->nSample>0 && nEqnSampleCol ){ + if( p->nSample>0 && nEqnSampleCol + && OptimizationEnabled(pParse->db, SQLITE_Stat34) + ){ if( nEq==pBuilder->nRecValid ){ UnpackedRecord *pRec = pBuilder->pRec; tRowcnt a[2]; @@ -1857,40 +1919,40 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ ** Free a WhereInfo structure */ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ - if( ALWAYS(pWInfo) ){ - int i; - for(i=0; inLevel; i++){ - WhereLevel *pLevel = &pWInfo->a[i]; - if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ - sqlite3DbFree(db, pLevel->u.in.aInLoop); - } + int i; + assert( pWInfo!=0 ); + for(i=0; inLevel; i++){ + WhereLevel *pLevel = &pWInfo->a[i]; + if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ + sqlite3DbFree(db, pLevel->u.in.aInLoop); } - sqlite3WhereClauseClear(&pWInfo->sWC); - while( pWInfo->pLoops ){ - WhereLoop *p = pWInfo->pLoops; - pWInfo->pLoops = p->pNextLoop; - whereLoopDelete(db, p); - } - sqlite3DbFreeNN(db, pWInfo); } + sqlite3WhereClauseClear(&pWInfo->sWC); + while( pWInfo->pLoops ){ + WhereLoop *p = pWInfo->pLoops; + pWInfo->pLoops = p->pNextLoop; + whereLoopDelete(db, p); + } + sqlite3DbFreeNN(db, pWInfo); } /* ** Return TRUE if all of the following are true: ** ** (1) X has the same or lower cost that Y -** (2) X is a proper subset of Y -** (3) X skips at least as many columns as Y -** -** By "proper subset" we mean that X uses fewer WHERE clause terms -** than Y and that every WHERE clause term used by X is also used -** by Y. +** (2) X uses fewer WHERE clause terms than Y +** (3) Every WHERE clause term used by X is also used by Y +** (4) X skips at least as many columns as Y +** (5) If X is a covering index, than Y is too ** +** Conditions (2) and (3) mean that X is a "proper subset" of Y. ** If X is a proper subset of Y then Y is a better choice and ought ** to have a lower cost. This routine returns TRUE when that cost -** relationship is inverted and needs to be adjusted. The third rule +** relationship is inverted and needs to be adjusted. Constraint (4) ** was added because if X uses skip-scan less than Y it still might -** deserve a lower cost even if it is a proper subset of Y. +** deserve a lower cost even if it is a proper subset of Y. Constraint (5) +** was added because a covering index probably deserves to have a lower cost +** than a non-covering index even if it is a proper subset. */ static int whereLoopCheaperProperSubset( const WhereLoop *pX, /* First WhereLoop to compare */ @@ -1912,6 +1974,10 @@ static int whereLoopCheaperProperSubset( } if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ } + if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 + && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ + return 0; /* Constraint (5) */ + } return 1; /* All conditions meet */ } @@ -2060,6 +2126,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ sqlite3 *db = pWInfo->pParse->db; int rc; + /* Stop the search once we hit the query planner search limit */ + if( pBuilder->iPlanLimit==0 ){ + WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n")); + if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0; + return SQLITE_DONE; + } + pBuilder->iPlanLimit--; + /* If pBuilder->pOrSet is defined, then only keep track of the costs ** and prereqs. */ @@ -2344,8 +2418,8 @@ static int whereLoopAddBtreeIndex( pNew = pBuilder->pNew; if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; - WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n", - pProbe->zName, pNew->u.btree.nEq)); + WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d\n", + pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq)); assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); @@ -2391,15 +2465,12 @@ static int whereLoopAddBtreeIndex( ** to mix with a lower range bound from some other source */ if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; - /* Do not allow IS constraints from the WHERE clause to be used by the + /* Do not allow constraints from the WHERE clause to be used by the ** right table of a LEFT JOIN. Only constraints in the ON clause are ** allowed */ if( (pSrc->fg.jointype & JT_LEFT)!=0 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - && (eOp & (WO_IS|WO_ISNULL))!=0 ){ - testcase( eOp & WO_IS ); - testcase( eOp & WO_ISNULL ); continue; } @@ -2425,7 +2496,6 @@ static int whereLoopAddBtreeIndex( if( eOp & WO_IN ){ Expr *pExpr = pTerm->pExpr; - pNew->wsFlags |= WHERE_COLUMN_IN; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ int i; @@ -2445,17 +2515,55 @@ static int whereLoopAddBtreeIndex( assert( nIn>0 ); /* RHS always has 2 or more terms... The parser ** changes "x IN (?)" into "x=?". */ } + if( pProbe->hasStat1 ){ + LogEst M, logK, safetyMargin; + /* Let: + ** N = the total number of rows in the table + ** K = the number of entries on the RHS of the IN operator + ** M = the number of rows in the table that match terms to the + ** to the left in the same index. If the IN operator is on + ** the left-most index column, M==N. + ** + ** Given the definitions above, it is better to omit the IN operator + ** from the index lookup and instead do a scan of the M elements, + ** testing each scanned row against the IN operator separately, if: + ** + ** M*log(K) < K*log(N) + ** + ** Our estimates for M, K, and N might be inaccurate, so we build in + ** a safety margin of 2 (LogEst: 10) that favors using the IN operator + ** with the index, as using an index has better worst-case behavior. + ** If we do not have real sqlite_stat1 data, always prefer to use + ** the index. + */ + M = pProbe->aiRowLogEst[saved_nEq]; + logK = estLog(nIn); + safetyMargin = 10; /* TUNING: extra weight for indexed IN */ + if( M + logK + safetyMargin < nIn + rLogSize ){ + WHERETRACE(0x40, + ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n", + saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); + continue; + }else{ + WHERETRACE(0x40, + ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n", + saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); + } + } + pNew->wsFlags |= WHERE_COLUMN_IN; }else if( eOp & (WO_EQ|WO_IS) ){ int iCol = pProbe->aiColumn[saved_nEq]; pNew->wsFlags |= WHERE_COLUMN_EQ; assert( saved_nEq==pNew->u.btree.nEq ); if( iCol==XN_ROWID - || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) + || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ - if( iCol>=0 && pProbe->uniqNotNull==0 ){ - pNew->wsFlags |= WHERE_UNQ_WANTED; - }else{ + if( iCol==XN_ROWID || pProbe->uniqNotNull + || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) + ){ pNew->wsFlags |= WHERE_ONEROW; + }else{ + pNew->wsFlags |= WHERE_UNQ_WANTED; } } }else if( eOp & WO_ISNULL ){ @@ -2521,6 +2629,7 @@ static int whereLoopAddBtreeIndex( && pProbe->nSample && pNew->u.btree.nEq<=pProbe->nSampleCol && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) + && OptimizationEnabled(db, SQLITE_Stat34) ){ Expr *pExpr = pTerm->pExpr; if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){ @@ -2609,6 +2718,7 @@ static int whereLoopAddBtreeIndex( if( saved_nEq==saved_nSkip && saved_nEq+1nKeyCol && pProbe->noSkipScan==0 + && OptimizationEnabled(db, SQLITE_SkipScan) && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK ){ @@ -2629,8 +2739,8 @@ static int whereLoopAddBtreeIndex( pNew->wsFlags = saved_wsFlags; } - WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n", - pProbe->zName, saved_nEq, rc)); + WHERETRACE(0x800, ("END %s.addBtreeIdx(%s), nEq=%d, rc=%d\n", + pProbe->pTable->zName, pProbe->zName, saved_nEq, rc)); return rc; } @@ -2663,7 +2773,7 @@ static int indexMightHelpWithOrderBy( }else if( (aColExpr = pIndex->aColExpr)!=0 ){ for(jj=0; jjnKeyCol; jj++){ if( pIndex->aiColumn[jj]!=XN_EXPR ) continue; - if( sqlite3ExprCompare(0, pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ + if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ return 1; } } @@ -2672,24 +2782,6 @@ static int indexMightHelpWithOrderBy( return 0; } -/* -** Return a bitmask where 1s indicate that the corresponding column of -** the table is used by an index. Only the first 63 columns are considered. -*/ -static Bitmask columnsInIndex(Index *pIdx){ - Bitmask m = 0; - int j; - for(j=pIdx->nColumn-1; j>=0; j--){ - int x = pIdx->aiColumn[j]; - if( x>=0 ){ - testcase( x==BMS-1 ); - testcase( x==BMS-2 ); - if( xrSetup = rLogSize + rSize + 4; + pNew->rSetup = rLogSize + rSize; if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){ - pNew->rSetup += 24; + pNew->rSetup += 28; + }else{ + pNew->rSetup -= 10; } ApplyCostMultiplier(pNew->rSetup, pTab->costMult); if( pNew->rSetup<0 ) pNew->rSetup = 0; @@ -2859,14 +2953,17 @@ static int whereLoopAddBtree( } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ - /* Loop over all indices - */ - for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ + /* Loop over all indices. If there was an INDEXED BY clause, then only + ** consider index pProbe. */ + for(; rc==SQLITE_OK && pProbe; + pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ + ){ if( pProbe->pPartIdxWhere!=0 && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ continue; /* Partial index inappropriate for this query */ } + if( pProbe->bNoQuery ) continue; rSize = pProbe->aiRowLogEst[0]; pNew->u.btree.nEq = 0; pNew->u.btree.nBtm = 0; @@ -2900,7 +2997,7 @@ static int whereLoopAddBtree( pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; m = 0; }else{ - m = pSrc->colUsed & ~columnsInIndex(pProbe); + m = pSrc->colUsed & pProbe->colNotIdxed; pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; } @@ -2971,10 +3068,6 @@ static int whereLoopAddBtree( pBuilder->nRecValid = 0; pBuilder->pRec = 0; #endif - - /* If there was an INDEXED BY clause, then only that one index is - ** considered. */ - if( pSrc->pIBIndex ) break; } return rc; } @@ -3069,9 +3162,9 @@ static int whereLoopAddVirtualOne( || pNew->aLTerm[iTerm]!=0 || pIdxCons->usable==0 ){ - rc = SQLITE_ERROR; sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - return rc; + testcase( pIdxInfo->needToFreeIdxStr ); + return SQLITE_ERROR; } testcase( iTerm==nConstraint-1 ); testcase( j==0 ); @@ -3099,6 +3192,15 @@ static int whereLoopAddVirtualOne( pNew->u.vtab.omitMask &= ~mNoOmit; pNew->nLTerm = mxTerm+1; + for(i=0; i<=mxTerm; i++){ + if( pNew->aLTerm[i]==0 ){ + /* The non-zero argvIdx values must be contiguous. Raise an + ** error if they are not */ + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); + testcase( pIdxInfo->needToFreeIdxStr ); + return SQLITE_ERROR; + } + } assert( pNew->nLTerm<=pNew->nLSlot ); pNew->u.vtab.idxNum = pIdxInfo->idxNum; pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; @@ -3129,6 +3231,27 @@ static int whereLoopAddVirtualOne( return rc; } +/* +** If this function is invoked from within an xBestIndex() callback, it +** returns a pointer to a buffer containing the name of the collation +** sequence associated with element iCons of the sqlite3_index_info.aConstraint +** array. Or, if iCons is out of range or there is no active xBestIndex +** call, return NULL. +*/ +const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + const char *zRet = 0; + if( iCons>=0 && iConsnConstraint ){ + CollSeq *pC = 0; + int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; + Expr *pX = pHidden->pWC->a[iTerm].pExpr; + if( pX->pLeft ){ + pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight); + } + zRet = (pC ? pC->zName : sqlite3StrBINARY); + } + return zRet; +} /* ** Add all WhereLoop objects for a table of the join identified by @@ -3193,6 +3316,7 @@ static int whereLoopAddVirtual( } /* First call xBestIndex() with all constraints usable. */ + WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); WHERETRACE(0x40, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); @@ -3268,6 +3392,7 @@ static int whereLoopAddVirtual( if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); sqlite3DbFreeNN(pParse->db, p); + WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -3415,9 +3540,11 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ /* Loop over the tables in the join, from left to right */ pNew = pBuilder->pNew; whereLoopInit(pNew); + pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; for(iTab=0, pItem=pTabList->a; pItemiTab = iTab; + pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){ /* This condition is true when pItem is the FROM clause term on the @@ -3439,11 +3566,19 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ { rc = whereLoopAddBtree(pBuilder, mPrereq); } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){ rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable); } mPrior |= pNew->maskSelf; - if( rc || db->mallocFailed ) break; + if( rc || db->mallocFailed ){ + if( rc==SQLITE_DONE ){ + /* We hit the query planner search limit set by iPlanLimit */ + sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search"); + rc = SQLITE_OK; + }else{ + break; + } + } } whereLoopClear(db, pNew); @@ -3573,14 +3708,10 @@ static i8 wherePathSatisfiesOrderBy( if( j>=pLoop->nLTerm ) continue; } if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ - const char *z1, *z2; - pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); - if( !pColl ) pColl = db->pDfltColl; - z1 = pColl->zName; - pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr); - if( !pColl ) pColl = db->pDfltColl; - z2 = pColl->zName; - if( sqlite3StrICmp(z1, z2)!=0 ) continue; + if( sqlite3ExprCollSeqMatch(pWInfo->pParse, + pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){ + continue; + } testcase( pTerm->pExpr->op==TK_IS ); } obSat |= MASKBIT(i); @@ -3652,7 +3783,7 @@ static i8 wherePathSatisfiesOrderBy( if( pIndex ){ iColumn = pIndex->aiColumn[j]; revIdx = pIndex->aSortOrder[j]; - if( iColumn==pIndex->pTable->iPKey ) iColumn = -1; + if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; }else{ iColumn = XN_ROWID; revIdx = 0; @@ -3679,19 +3810,18 @@ static i8 wherePathSatisfiesOrderBy( testcase( wctrlFlags & WHERE_GROUPBY ); testcase( wctrlFlags & WHERE_DISTINCTBY ); if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; - if( iColumn>=(-1) ){ + if( iColumn>=XN_ROWID ){ if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; if( pOBExpr->iColumn!=iColumn ) continue; }else{ - if( sqlite3ExprCompare(0, - pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){ + Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr; + if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ continue; } } - if( iColumn>=0 ){ - pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); - if( !pColl ) pColl = db->pDfltColl; + if( iColumn!=XN_ROWID ){ + pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; } pLoop->u.btree.nIdxCol = j+1; @@ -3951,12 +4081,15 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; - if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){ + if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){ /* Do not use an automatic index if the this loop is expected - ** to run less than 2 times. */ + ** to run less than 1.25 times. It is tempting to also exclude + ** automatic index usage on an outer loop, but sometimes an automatic + ** index is useful in the outer loop of a correlated subquery. */ assert( 10==sqlite3LogEst(2) ); continue; } + /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); @@ -3976,7 +4109,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo, nRowEst, nOrderBy, isOrdered ); } - rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]); + /* TUNING: Add a small extra penalty (5) to sorting as an + ** extra encouragment to the query planner to select a plan + ** where the rows emerge in the correct order without any sorting + ** required. */ + rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; WHERETRACE(0x002, ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", @@ -4166,6 +4303,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } } + pWInfo->bOrderedInnerLoop = 0; if( pWInfo->pOrderBy ){ if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ @@ -4277,7 +4415,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ } if( j!=pIdx->nKeyCol ) continue; pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; - if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){ + if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){ pLoop->wsFlags |= WHERE_IDX_ONLY; } pLoop->nLTerm = j; @@ -4328,6 +4466,7 @@ static int exprIsDeterministic(Expr *p){ memset(&w, 0, sizeof(w)); w.eCode = 1; w.xExprCallback = exprNodeIsDeterministic; + w.xSelectCallback = sqlite3SelectWalkFail; sqlite3WalkExpr(&w, p); return w.eCode; } @@ -4537,37 +4676,39 @@ WhereInfo *sqlite3WhereBegin( if( wctrlFlags & WHERE_WANT_DISTINCT ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } - } - - /* Assign a bit from the bitmask to every term in the FROM clause. - ** - ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in - ** pTabList, not just the first nTabList tables. nTabList is normally - ** equal to pTabList->nSrc but might be shortened to 1 if the - ** WHERE_OR_SUBCLAUSE flag is set. - */ - for(ii=0; iinSrc; ii++){ - createMask(pMaskSet, pTabList->a[ii].iCursor); - sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); - } -#ifdef SQLITE_DEBUG - { - Bitmask mx = 0; - for(ii=0; iinSrc; ii++){ - Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); - assert( m>=mx ); - mx = m; + ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); + }else{ + /* Assign a bit from the bitmask to every term in the FROM clause. + ** + ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in + ** pTabList, not just the first nTabList tables. nTabList is normally + ** equal to pTabList->nSrc but might be shortened to 1 if the + ** WHERE_OR_SUBCLAUSE flag is set. + */ + ii = 0; + do{ + createMask(pMaskSet, pTabList->a[ii].iCursor); + sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); + }while( (++ii)nSrc ); + #ifdef SQLITE_DEBUG + { + Bitmask mx = 0; + for(ii=0; iinSrc; ii++){ + Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); + assert( m>=mx ); + mx = m; + } } + #endif } -#endif - + /* Analyze all of the subexpressions. */ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); if( db->mallocFailed ) goto whereBeginError; @@ -4585,6 +4726,7 @@ WhereInfo *sqlite3WhereBegin( */ for(ii=0; iinTerm; ii++){ WhereTerm *pT = &sWLB.pWC->a[ii]; + if( pT->wtFlags & TERM_VIRTUAL ) continue; if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL); pT->wtFlags |= TERM_CODED; @@ -4672,35 +4814,80 @@ WhereInfo *sqlite3WhereBegin( } } #endif - /* Attempt to omit tables from the join that do not effect the result */ + + /* Attempt to omit tables from the join that do not affect the result. + ** For a table to not affect the result, the following must be true: + ** + ** 1) The query must not be an aggregate. + ** 2) The table must be the RHS of a LEFT JOIN. + ** 3) Either the query must be DISTINCT, or else the ON or USING clause + ** must contain a constraint that limits the scan of the table to + ** at most a single row. + ** 4) The table must not be referenced by any part of the query apart + ** from its own USING or ON clause. + ** + ** For example, given: + ** + ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); + ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); + ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); + ** + ** then table t2 can be omitted from the following: + ** + ** SELECT v1, v3 FROM t1 + ** LEFT JOIN t2 USING (t1.ipk=t2.ipk) + ** LEFT JOIN t3 USING (t1.ipk=t3.ipk) + ** + ** or from: + ** + ** SELECT DISTINCT v1, v3 FROM t1 + ** LEFT JOIN t2 + ** LEFT JOIN t3 USING (t1.ipk=t3.ipk) + */ + notReady = ~(Bitmask)0; if( pWInfo->nLevel>=2 - && pResultSet!=0 + && pResultSet!=0 /* guarantees condition (1) above */ && OptimizationEnabled(db, SQLITE_OmitNoopJoin) ){ + int i; Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet); if( sWLB.pOrderBy ){ tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); } - while( pWInfo->nLevel>=2 ){ + for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; - pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; - if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break; + struct SrcList_item *pItem; + pLoop = pWInfo->a[i].pWLoop; + pItem = &pWInfo->pTabList->a[pLoop->iTab]; + if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 && (pLoop->wsFlags & WHERE_ONEROW)==0 ){ - break; + continue; } - if( (tabUsed & pLoop->maskSelf)!=0 ) break; + if( (tabUsed & pLoop->maskSelf)!=0 ) continue; pEnd = sWLB.pWC->a + sWLB.pWC->nTerm; for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 - && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - ){ - break; + if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ + if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + || pTerm->pExpr->iRightJoinTable!=pItem->iCursor + ){ + break; + } } } - if( pTerm drop loop %c not used\n", pLoop->cId)); + notReady &= ~pLoop->maskSelf; + for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + pTerm->wtFlags |= TERM_CODED; + } + } + if( i!=pWInfo->nLevel-1 ){ + int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); + memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); + } pWInfo->nLevel--; nTabList--; } @@ -4710,15 +4897,32 @@ WhereInfo *sqlite3WhereBegin( /* If the caller is an UPDATE or DELETE statement that is requesting ** to use a one-pass algorithm, determine if this is appropriate. + ** + ** A one-pass approach can be used if the caller has requested one + ** and either (a) the scan visits at most one row or (b) each + ** of the following are true: + ** + ** * the caller has indicated that a one-pass approach can be used + ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and + ** * the table is not a virtual table, and + ** * either the scan does not use the OR optimization or the caller + ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified + ** for DELETE). + ** + ** The last qualification is because an UPDATE statement uses + ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can + ** use a one-pass approach, and this is not set accurately for scans + ** that use the OR optimization. */ assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ int wsFlags = pWInfo->a[0].pWLoop->wsFlags; int bOnerow = (wsFlags & WHERE_ONEROW)!=0; - if( bOnerow - || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0 - && 0==(wsFlags & WHERE_VIRTUALTABLE)) - ){ + if( bOnerow || ( + 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) + && 0==(wsFlags & WHERE_VIRTUALTABLE) + && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) + )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ @@ -4790,7 +4994,7 @@ WhereInfo *sqlite3WhereBegin( Index *pIx = pLoop->u.btree.pIndex; int iIndexCur; int op = OP_OpenRead; - /* iAuxArg is always set if to a positive value if ONEPASS is possible */ + /* iAuxArg is always set to a positive value if ONEPASS is possible */ assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 @@ -4855,7 +5059,6 @@ WhereInfo *sqlite3WhereBegin( ** loop below generates code for a single nested loop of the VM ** program. */ - notReady = ~(Bitmask)0; for(ii=0; iiiFrom, wctrlFlags + pParse, pTabList, pLevel, wctrlFlags ); pLevel->addrBody = sqlite3VdbeCurrentAddr(v); notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady); @@ -4892,6 +5095,26 @@ whereBeginError: return 0; } +/* +** Part of sqlite3WhereEnd() will rewrite opcodes to reference the +** index rather than the main table. In SQLITE_DEBUG mode, we want +** to trace those changes if PRAGMA vdbe_addoptrace=on. This routine +** does that. +*/ +#ifndef SQLITE_DEBUG +# define OpcodeRewriteTrace(D,K,P) /* no-op */ +#else +# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P) + static void sqlite3WhereOpcodeRewriteTrace( + sqlite3 *db, + int pc, + VdbeOp *pOp + ){ + if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; + sqlite3VdbePrintOp(0, pc, pOp); + } +#endif + /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. @@ -4908,7 +5131,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Generate loop termination code. */ VdbeModuleComment((v, "End WHERE-core")); - sqlite3ExprCacheClear(pParse); for(i=pWInfo->nLevel-1; i>=0; i--){ int addr; pLevel = &pWInfo->a[i]; @@ -4919,6 +5141,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ Index *pIdx; int n; if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED + && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */ && (pLoop->wsFlags & WHERE_INDEXED)!=0 && (pIdx = pLoop->u.btree.pIndex)->hasStat1 && (n = pLoop->u.btree.nIdxCol)>0 @@ -4958,10 +5181,17 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ + if( pIn->nPrefix ){ + assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2, + pIn->iBase, pIn->nPrefix); + VdbeCoverage(v); + } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next); } sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } @@ -4985,7 +5215,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); if( (ws & WHERE_IDX_ONLY)==0 ){ - sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); + assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); } if( (ws & WHERE_INDEXED) || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) @@ -5051,10 +5282,19 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ){ last = sqlite3VdbeCurrentAddr(v); k = pLevel->addrBody; +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); + } +#endif pOp = sqlite3VdbeGetOp(v, k); for(; kp1!=pLevel->iTabCur ) continue; - if( pOp->opcode==OP_Column ){ + if( pOp->opcode==OP_Column +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + || pOp->opcode==OP_Offset +#endif + ){ int x = pOp->p2; assert( pIdx->pTable==pTab ); if( !HasRowid(pTab) ){ @@ -5066,16 +5306,22 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( x>=0 ){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); } assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; + OpcodeRewriteTrace(db, k, pOp); }else if( pOp->opcode==OP_IfNullRow ){ pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); } } +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); +#endif } } diff --git a/src/whereInt.h b/src/whereInt.h index bac81da721..209ac42ee2 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -19,7 +19,7 @@ ** Trace output macros */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ int sqlite3WhereTrace; +/***/ extern int sqlite3WhereTrace; #endif #if defined(SQLITE_DEBUG) \ && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) @@ -82,6 +82,8 @@ struct WhereLevel { struct InLoop { int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ + int iBase; /* Base register of multi-key index record */ + int nPrefix; /* Number of prior entires in the key */ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ @@ -320,6 +322,7 @@ struct WhereClause { WhereInfo *pWInfo; /* WHERE clause processing context */ WhereClause *pOuter; /* Outer conjunction */ u8 op; /* Split operator. TK_AND or TK_OR */ + u8 hasOr; /* True if any a[].eOperator is WO_OR */ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ @@ -399,12 +402,33 @@ struct WhereLoopBuilder { int nRecValid; /* Number of valid fields currently in pRec */ #endif unsigned int bldFlags; /* SQLITE_BLDF_* flags */ + unsigned int iPlanLimit; /* Search limiter */ }; /* Allowed values for WhereLoopBuider.bldFlags */ #define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */ #define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ +/* The WhereLoopBuilder.iPlanLimit is used to limit the number of +** index+constraint combinations the query planner will consider for a +** particular query. If this parameter is unlimited, then certain +** pathological queries can spend excess time in the sqlite3WhereBegin() +** routine. The limit is high enough that is should not impact real-world +** queries. +** +** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is +** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM +** clause is processed, so that every table in a join is guaranteed to be +** able to propose a some index+constraint combinations even if the initial +** baseline limit was exhausted by prior tables of the join. +*/ +#ifndef SQLITE_QUERY_PLANNER_LIMIT +# define SQLITE_QUERY_PLANNER_LIMIT 20000 +#endif +#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR +# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 +#endif + /* ** The WHERE clause processing routine has two halves. The ** first part does the start of the WHERE loop and the second @@ -467,12 +491,10 @@ int sqlite3WhereExplainOneScan( Parse *pParse, /* Parse context */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ - int iLevel, /* Value for "level" column of output */ - int iFrom, /* Value for "from" column of output */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ); #else -# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0 +# define sqlite3WhereExplainOneScan(u,v,w,x) 0 #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS void sqlite3WhereAddScanStatus( @@ -495,6 +517,7 @@ void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); void sqlite3WhereClauseClear(WhereClause*); void sqlite3WhereSplit(WhereClause*,Expr*,u8); Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); +Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); @@ -515,7 +538,6 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); ** WO_LE == SQLITE_INDEX_CONSTRAINT_LE ** WO_GT == SQLITE_INDEX_CONSTRAINT_GT ** WO_GE == SQLITE_INDEX_CONSTRAINT_GE -** WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH */ #define WO_IN 0x0001 #define WO_EQ 0x0002 @@ -523,7 +545,7 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); #define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) #define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) #define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) -#define WO_MATCH 0x0040 +#define WO_AUX 0x0040 /* Op useful to virtual tables only */ #define WO_IS 0x0080 #define WO_ISNULL 0x0100 #define WO_OR 0x0200 /* Two or more OR-connected terms */ @@ -558,3 +580,4 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ +#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ diff --git a/src/wherecode.c b/src/wherecode.c index 528aeec2b0..f337006b97 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -51,23 +51,23 @@ static void explainAppendTerm( int i; assert( nTerm>=1 ); - if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5); + if( bAnd ) sqlite3_str_append(pStr, " AND ", 5); - if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); for(i=0; i1 ) sqlite3StrAccumAppend(pStr, ")", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1); - sqlite3StrAccumAppend(pStr, zOp, 1); + sqlite3_str_append(pStr, zOp, 1); - if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); for(i=0; i1 ) sqlite3StrAccumAppend(pStr, ")", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1); } /* @@ -91,11 +91,11 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ int i, j; if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; - sqlite3StrAccumAppend(pStr, " (", 2); + sqlite3_str_append(pStr, " (", 2); for(i=0; i=nSkip ? "%s=?" : "ANY(%s)", z); + if( i ) sqlite3_str_append(pStr, " AND ", 5); + sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z); } j = i; @@ -106,7 +106,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); } - sqlite3StrAccumAppend(pStr, ")", 1); + sqlite3_str_append(pStr, ")", 1); } /* @@ -122,19 +122,16 @@ int sqlite3WhereExplainOneScan( Parse *pParse, /* Parse context */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ - int iLevel, /* Value for "level" column of output */ - int iFrom, /* Value for "from" column of output */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ int ret = 0; #if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( pParse->explain==2 ) + if( sqlite3ParseToplevel(pParse)->explain==2 ) #endif { struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ - int iId = pParse->iSelectId; /* Select id (left-most output column) */ int isSearch; /* True for a SEARCH. False for SCAN. */ WhereLoop *pLoop; /* The controlling WhereLoop object */ u32 flags; /* Flags that describe this loop */ @@ -151,15 +148,15 @@ int sqlite3WhereExplainOneScan( || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); - sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); + sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN"); if( pItem->pSelect ){ - sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId); + sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId); }else{ - sqlite3XPrintf(&str, " TABLE %s", pItem->zName); + sqlite3_str_appendf(&str, " TABLE %s", pItem->zName); } if( pItem->zAlias ){ - sqlite3XPrintf(&str, " AS %s", pItem->zAlias); + sqlite3_str_appendf(&str, " AS %s", pItem->zAlias); } if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; @@ -182,8 +179,8 @@ int sqlite3WhereExplainOneScan( zFmt = "INDEX %s"; } if( zFmt ){ - sqlite3StrAccumAppend(&str, " USING ", 7); - sqlite3XPrintf(&str, zFmt, pIdx->zName); + sqlite3_str_append(&str, " USING ", 7); + sqlite3_str_appendf(&str, zFmt, pIdx->zName); explainIndexRange(&str, pLoop); } }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ @@ -198,23 +195,26 @@ int sqlite3WhereExplainOneScan( assert( flags&WHERE_TOP_LIMIT); zRangeOp = "<"; } - sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); + sqlite3_str_appendf(&str, + " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ - sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s", + sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS if( pLoop->nOut>=10 ){ - sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); + sqlite3_str_appendf(&str, " (~%llu rows)", + sqlite3LogEstToInt(pLoop->nOut)); }else{ - sqlite3StrAccumAppend(&str, " (~1 row)", 9); + sqlite3_str_append(&str, " (~1 row)", 9); } #endif zMsg = sqlite3StrAccumFinish(&str); - ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC); + ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), + pParse->addrExplain, 0, zMsg,P4_DYNAMIC); } return ret; } @@ -294,8 +294,8 @@ void sqlite3WhereAddScanStatus( */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ int nLoop = 0; - while( ALWAYS(pTerm!=0) - && (pTerm->wtFlags & TERM_CODED)==0 + assert( pTerm!=0 ); + while( (pTerm->wtFlags & TERM_CODED)==0 && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) && (pLevel->notReady & pTerm->prereqAll)==0 ){ @@ -306,6 +306,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ } if( pTerm->iParent<0 ) break; pTerm = &pTerm->pWC->a[pTerm->iParent]; + assert( pTerm!=0 ); pTerm->nChild--; if( pTerm->nChild!=0 ) break; nLoop++; @@ -346,7 +347,6 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ /* Code the OP_Affinity opcode if there is anything left to do. */ if( n>0 ){ sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); - sqlite3ExprCacheAffinityChange(pParse, base, n); } } @@ -376,6 +376,102 @@ static void updateRangeAffinityStr( } } + +/* +** pX is an expression of the form: (vector) IN (SELECT ...) +** In other words, it is a vector IN operator with a SELECT clause on the +** LHS. But not all terms in the vector are indexable and the terms might +** not be in the correct order for indexing. +** +** This routine makes a copy of the input pX expression and then adjusts +** the vector on the LHS with corresponding changes to the SELECT so that +** the vector contains only index terms and those terms are in the correct +** order. The modified IN expression is returned. The caller is responsible +** for deleting the returned expression. +** +** Example: +** +** CREATE TABLE t1(a,b,c,d,e,f); +** CREATE INDEX t1x1 ON t1(e,c); +** SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2) +** \_______________________________________/ +** The pX expression +** +** Since only columns e and c can be used with the index, in that order, +** the modified IN expression that is returned will be: +** +** (e,c) IN (SELECT z,x FROM t2) +** +** The reduced pX is different from the original (obviously) and thus is +** only used for indexing, to improve performance. The original unaltered +** IN expression must also be run on each output row for correctness. +*/ +static Expr *removeUnindexableInClauseTerms( + Parse *pParse, /* The parsing context */ + int iEq, /* Look at loop terms starting here */ + WhereLoop *pLoop, /* The current loop */ + Expr *pX /* The IN expression to be reduced */ +){ + sqlite3 *db = pParse->db; + Expr *pNew = sqlite3ExprDup(db, pX, 0); + if( db->mallocFailed==0 ){ + ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */ + ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */ + ExprList *pRhs = 0; /* New RHS after modifications */ + ExprList *pLhs = 0; /* New LHS after mods */ + int i; /* Loop counter */ + Select *pSelect; /* Pointer to the SELECT on the RHS */ + + for(i=iEq; inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iField = pLoop->aLTerm[i]->iField - 1; + assert( pOrigRhs->a[iField].pExpr!=0 ); + pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); + pOrigRhs->a[iField].pExpr = 0; + assert( pOrigLhs->a[iField].pExpr!=0 ); + pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr); + pOrigLhs->a[iField].pExpr = 0; + } + } + sqlite3ExprListDelete(db, pOrigRhs); + sqlite3ExprListDelete(db, pOrigLhs); + pNew->pLeft->x.pList = pLhs; + pNew->x.pSelect->pEList = pRhs; + if( pLhs && pLhs->nExpr==1 ){ + /* Take care here not to generate a TK_VECTOR containing only a + ** single value. Since the parser never creates such a vector, some + ** of the subroutines do not handle this case. */ + Expr *p = pLhs->a[0].pExpr; + pLhs->a[0].pExpr = 0; + sqlite3ExprDelete(db, pNew->pLeft); + pNew->pLeft = p; + } + pSelect = pNew->x.pSelect; + if( pSelect->pOrderBy ){ + /* If the SELECT statement has an ORDER BY clause, zero the + ** iOrderByCol variables. These are set to non-zero when an + ** ORDER BY term exactly matches one of the terms of the + ** result-set. Since the result-set of the SELECT statement may + ** have been modified or reordered, these variables are no longer + ** set correctly. Since setting them is just an optimization, + ** it's easiest just to zero them here. */ + ExprList *pOrderBy = pSelect->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } + +#if 0 + printf("For indexing, change the IN expr:\n"); + sqlite3TreeViewExpr(0, pX, 0); + printf("Into:\n"); + sqlite3TreeViewExpr(0, pNew, 0); +#endif + } + return pNew; +} + + /* ** Generate code for a single equality term of the WHERE clause. An equality ** term can be either X=expr or X IN (...). pTerm is the term to be @@ -438,68 +534,23 @@ static int codeEqualityTerm( } } for(i=iEq;inLTerm; i++){ - if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++; + assert( pLoop->aLTerm[i]!=0 ); + if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; } if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); }else{ - Select *pSelect = pX->x.pSelect; sqlite3 *db = pParse->db; - u16 savedDbOptFlags = db->dbOptFlags; - ExprList *pOrigRhs = pSelect->pEList; - ExprList *pOrigLhs = pX->pLeft->x.pList; - ExprList *pRhs = 0; /* New Select.pEList for RHS */ - ExprList *pLhs = 0; /* New pX->pLeft vector */ + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - for(i=iEq;inLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iField = pLoop->aLTerm[i]->iField - 1; - Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0); - Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0); - - pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs); - pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs); - } - } if( !db->mallocFailed ){ - Expr *pLeft = pX->pLeft; - - if( pSelect->pOrderBy ){ - /* If the SELECT statement has an ORDER BY clause, zero the - ** iOrderByCol variables. These are set to non-zero when an - ** ORDER BY term exactly matches one of the terms of the - ** result-set. Since the result-set of the SELECT statement may - ** have been modified or reordered, these variables are no longer - ** set correctly. Since setting them is just an optimization, - ** it's easiest just to zero them here. */ - ExprList *pOrderBy = pSelect->pOrderBy; - for(i=0; inExpr; i++){ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } - } - - /* Take care here not to generate a TK_VECTOR containing only a - ** single value. Since the parser never creates such a vector, some - ** of the subroutines do not handle this case. */ - if( pLhs->nExpr==1 ){ - pX->pLeft = pLhs->a[0].pExpr; - }else{ - pLeft->x.pList = pLhs; - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq); - testcase( aiMap==0 ); - } - pSelect->pEList = pRhs; - db->dbOptFlags |= SQLITE_QueryFlattener; + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); - db->dbOptFlags = savedDbOptFlags; - testcase( aiMap!=0 && aiMap[0]!=0 ); - pSelect->pEList = pOrigRhs; - pLeft->x.pList = pOrigLhs; - pX->pLeft = pLeft; + pTerm->pExpr->iTable = pX->iTable; } - sqlite3ExprListDelete(pParse->db, pLhs); - sqlite3ExprListDelete(pParse->db, pRhs); + sqlite3ExprDelete(db, pX); + pX = pTerm->pExpr; } if( eType==IN_INDEX_INDEX_DESC ){ @@ -539,7 +590,14 @@ static int codeEqualityTerm( sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); if( i==iEq ){ pIn->iCur = iTab; - pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + pIn->iBase = iReg - i; + pIn->nPrefix = i; + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + }else{ + pIn->nPrefix = 0; + } }else{ pIn->eEndLoopOp = OP_Noop; } @@ -826,11 +884,8 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ struct CCurHint *pHint = pWalker->u.pCCurHint; if( pExpr->op==TK_COLUMN ){ if( pExpr->iTable!=pHint->iTabCur ){ - Vdbe *v = pWalker->pParse->pVdbe; int reg = ++pWalker->pParse->nMem; /* Register for column value */ - sqlite3ExprCodeGetColumnOfTable( - v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg - ); + sqlite3ExprCode(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ @@ -1017,7 +1072,7 @@ static void codeDeferredSeek( */ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); - if( sqlite3ExprIsVector(p) ){ + if( p && sqlite3ExprIsVector(p) ){ #ifndef SQLITE_OMIT_SUBQUERY if( (p->flags & EP_xIsSelect) ){ Vdbe *v = pParse->pVdbe; @@ -1062,7 +1117,7 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; - pExpr->pTab = 0; + pExpr->y.pTab = 0; return WRC_Prune; }else{ return WRC_Continue; @@ -1070,9 +1125,9 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ } /* -** For an indexes on expression X, locate every instance of expression X in pExpr -** and change that subexpression into a reference to the appropriate column of -** the index. +** For an indexes on expression X, locate every instance of expression X +** in pExpr and change that subexpression into a reference to the appropriate +** column of the index. */ static void whereIndexExprTrans( Index *pIdx, /* The Index */ @@ -1163,6 +1218,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ + assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) + || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0 + ); if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); @@ -1180,7 +1238,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeCoverage(v); - VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); + VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); pLevel->op = OP_Goto; }else @@ -1194,7 +1252,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( int nConstraint = pLoop->nLTerm; int iIn; /* Counter for IN constraints */ - sqlite3ExprCachePush(pParse); iReg = sqlite3GetTempRange(pParse, nConstraint+2); addrNotFound = pLevel->addrBrk; for(j=0; jaddrNxt; sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); - sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); - VdbeComment((v, "pk")); pLevel->op = OP_Noop; }else if( (pLoop->wsFlags & WHERE_IPK)!=0 && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 @@ -1343,7 +1396,15 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( sqlite3ExprIsVector(pX->pRight) ){ r1 = rTemp = sqlite3GetTempReg(pParse); codeExprOrVector(pParse, pX->pRight, r1, 1); - op = aMoveOp[(pX->op - TK_GT) | 0x0001]; + testcase( pX->op==TK_GT ); + testcase( pX->op==TK_GE ); + testcase( pX->op==TK_LT ); + testcase( pX->op==TK_LE ); + op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1]; + assert( pX->op!=TK_GT || op==OP_SeekGE ); + assert( pX->op!=TK_GE || op==OP_SeekGE ); + assert( pX->op!=TK_LT || op==OP_SeekLE ); + assert( pX->op!=TK_LE || op==OP_SeekLE ); }else{ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); disableTerm(pLevel, pStart); @@ -1355,7 +1416,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverageIf(v, pX->op==TK_LE); VdbeCoverageIf(v, pX->op==TK_LT); VdbeCoverageIf(v, pX->op==TK_GE); - sqlite3ExprCacheAffinityChange(pParse, r1, 1); sqlite3ReleaseTempReg(pParse, rTemp); }else{ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); @@ -1390,7 +1450,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( testOp!=OP_Noop ){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); VdbeCoverageIf(v, testOp==OP_Le); VdbeCoverageIf(v, testOp==OP_Lt); @@ -1595,6 +1654,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** above has already left the cursor sitting on the correct row, ** so no further seeking is needed */ }else{ + if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ + sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); + } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); @@ -1613,7 +1675,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( nConstraint = nEq; if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; - sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); codeExprOrVector(pParse, pRight, regBase+nEq, nTop); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 @@ -1657,6 +1718,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } + if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ + sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); + } + /* Seek the table cursor, if required */ if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ @@ -1667,7 +1732,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( )){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); VdbeCoverage(v); }else{ @@ -1687,9 +1751,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* If pIdx is an index on one or more expressions, then look through ** all the expressions in pWInfo and try to transform matching expressions ** into reference to index columns. + ** + ** Do not do this for the RHS of a LEFT JOIN. This is because the + ** expression may be evaluated after OP_NullRow has been executed on + ** the cursor. In this case it is important to do the full evaluation, + ** as the result of the expression may not be NULL, even if all table + ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a */ - whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); - + if( pLevel->iLeftJoin==0 ){ + whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); + } /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ @@ -1845,7 +1916,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( for(iTerm=0; iTermnTerm; iTerm++){ Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; - if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; @@ -1864,13 +1934,17 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** sub-WHERE clause is to to invoke the main loop body as a subroutine. */ wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); + ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR")); for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ WhereInfo *pSubWInfo; /* Info for single OR-term scan */ Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ int jmp1 = 0; /* Address of jump operation */ - if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ + assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 + || ExprHasProperty(pOrExpr, EP_FromJoin) + ); + if( pAndExpr ){ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; } @@ -1882,7 +1956,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pSubWInfo ){ WhereLoop *pSubLoop; int addrExplain = sqlite3WhereExplainOneScan( - pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 + pParse, pOrTab, &pSubWInfo->a[0], 0 ); sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); @@ -1892,23 +1966,23 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** row will be skipped in subsequent sub-WHERE clauses. */ if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ - int r; int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); if( HasRowid(pTab) ){ - r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid); jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, - r,iSet); + regRowid, iSet); VdbeCoverage(v); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); int nPk = pPk->nKeyCol; int iPk; + int r; /* Read the PK into an array of temp registers. */ r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPkaiColumn[iPk]; - sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk); } /* Check if the temp table already contains this key. If so, @@ -1981,6 +2055,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } } } + ExplainQueryPlanPop(pParse); pLevel->u.pCovidx = pCov; if( pCov ) pLevel->iIdxCur = iCovCur; if( pAndExpr ){ @@ -2053,7 +2128,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } pE = pTerm->pExpr; assert( pE!=0 ); - if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ + if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){ continue; } @@ -2066,7 +2141,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( continue; } - if( pTerm->wtFlags & TERM_LIKECOND ){ + if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){ /* If the TERM_LIKECOND flag is set, that means that the range search ** is sufficient to guarantee that the LIKE operator is true, so we ** can skip the call to the like(A,B) function. But this only works @@ -2076,8 +2151,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( continue; #else u32 x = pLevel->iLikeRepCntr; - assert( x>0 ); - skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1)); + if( x>0 ){ + skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1)); + } VdbeCoverage(v); #endif } @@ -2117,6 +2193,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; if( pAlt->wtFlags & (TERM_CODED) ) continue; + if( (pAlt->eOperator & WO_IN) + && (pAlt->pExpr->flags & EP_xIsSelect) + && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) + ){ + continue; + } testcase( pAlt->eOperator & WO_EQ ); testcase( pAlt->eOperator & WO_IS ); testcase( pAlt->eOperator & WO_IN ); @@ -2133,7 +2215,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); - sqlite3ExprCacheClear(pParse); for(pTerm=pWC->a, j=0; jnTerm; j++, pTerm++){ testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); diff --git a/src/whereexpr.c b/src/whereexpr.c index 325b054ea2..8f3791e798 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -194,18 +194,18 @@ static int isLikeOrGlob( int *pisComplete, /* True if the only wildcard is % in the last character */ int *pnoCase /* True if uppercase is equivalent to lowercase */ ){ - const u8 *z = 0; /* String on RHS of LIKE operator */ + const u8 *z = 0; /* String on RHS of LIKE operator */ Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ ExprList *pList; /* List of operands to the LIKE operator */ - int c; /* One character in z[] */ + u8 c; /* One character in z[] */ int cnt; /* Number of non-wildcard prefix characters */ - char wc[4]; /* Wildcard characters */ + u8 wc[4]; /* Wildcard characters */ sqlite3 *db = pParse->db; /* Database connection */ sqlite3_value *pVal = 0; int op; /* Opcode of pRight */ int rc; /* Result code to return */ - if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ + if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){ return 0; } #ifdef SQLITE_EBCDIC @@ -230,39 +230,22 @@ static int isLikeOrGlob( } if( z ){ - /* If the RHS begins with a digit or a minus sign, then the LHS must - ** be an ordinary column (not a virtual table column) with TEXT affinity. - ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false - ** even though "lhs LIKE rhs" is true. But if the RHS does not start - ** with a digit or '-', then "lhs LIKE rhs" will always be false if - ** the LHS is numeric and so the optimization still works. - */ - if( sqlite3Isdigit(z[0]) || z[0]=='-' ){ - if( pLeft->op!=TK_COLUMN - || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->pTab) /* Value might be numeric */ - ){ - sqlite3ValueFree(pVal); - return 0; - } - } - /* Count the number of prefix characters prior to the first wildcard */ cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; - if( c==wc[3] && z[cnt]!=0 ){ - if( z[cnt++]>0xc0 ) while( (z[cnt]&0xc0)==0x80 ){ cnt++; } - } + if( c==wc[3] && z[cnt]!=0 ) cnt++; } /* The optimization is possible only if (1) the pattern does not begin ** with a wildcard and if (2) the non-wildcard prefix does not end with - ** an (illegal 0xff) character. The second condition is necessary so + ** an (illegal 0xff) character, or (3) the pattern does not consist of + ** a single escape character. The second condition is necessary so ** that we can increment the prefix key to find an upper bound for the - ** range search. - */ - if( cnt!=0 && 255!=(u8)z[cnt-1] ){ + ** range search. The third is because the caller assumes that the pattern + ** consists of at least one character after all escapes have been + ** removed. */ + if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ @@ -279,6 +262,32 @@ static int isLikeOrGlob( zNew[iTo++] = zNew[iFrom]; } zNew[iTo] = 0; + + /* If the RHS begins with a digit or a minus sign, then the LHS must be + ** an ordinary column (not a virtual table column) with TEXT affinity. + ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false + ** even though "lhs LIKE rhs" is true. But if the RHS does not start + ** with a digit or '-', then "lhs LIKE rhs" will always be false if + ** the LHS is numeric and so the optimization still works. + ** + ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033 + ** The RHS pattern must not be '/%' because the termination condition + ** will then become "x<'0'" and if the affinity is numeric, will then + ** be converted into "x<0", which is incorrect. + */ + if( sqlite3Isdigit(zNew[0]) + || zNew[0]=='-' + || (zNew[0]+1=='0' && iTo==1) + ){ + if( pLeft->op!=TK_COLUMN + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + || IsVirtual(pLeft->y.pTab) /* Value might be numeric */ + ){ + sqlite3ExprDelete(db, pPrefix); + sqlite3ValueFree(pVal); + return 0; + } + } } *ppPrefix = pPrefix; @@ -314,48 +323,123 @@ static int isLikeOrGlob( #ifndef SQLITE_OMIT_VIRTUALTABLE /* -** Check to see if the given expression is of the form +** Check to see if the pExpr expression is a form that needs to be passed +** to the xBestIndex method of virtual tables. Forms of interest include: ** -** column OP expr +** Expression Virtual Table Operator +** ----------------------- --------------------------------- +** 1. column MATCH expr SQLITE_INDEX_CONSTRAINT_MATCH +** 2. column GLOB expr SQLITE_INDEX_CONSTRAINT_GLOB +** 3. column LIKE expr SQLITE_INDEX_CONSTRAINT_LIKE +** 4. column REGEXP expr SQLITE_INDEX_CONSTRAINT_REGEXP +** 5. column != expr SQLITE_INDEX_CONSTRAINT_NE +** 6. expr != column SQLITE_INDEX_CONSTRAINT_NE +** 7. column IS NOT expr SQLITE_INDEX_CONSTRAINT_ISNOT +** 8. expr IS NOT column SQLITE_INDEX_CONSTRAINT_ISNOT +** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL ** -** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a -** column of a virtual table. +** In every case, "column" must be a column of a virtual table. If there +** is a match, set *ppLeft to the "column" expression, set *ppRight to the +** "expr" expression (even though in forms (6) and (8) the column is on the +** right and the expression is on the left). Also set *peOp2 to the +** appropriate virtual table operator. The return value is 1 or 2 if there +** is a match. The usual return is 1, but if the RHS is also a column +** of virtual table in forms (5) or (7) then return 2. ** -** If it is then return TRUE. If not, return FALSE. +** If the expression matches none of the patterns above, return 0. */ -static int isMatchOfColumn( +static int isAuxiliaryVtabOperator( + sqlite3 *db, /* Parsing context */ Expr *pExpr, /* Test this expression */ - unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */ + unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ + Expr **ppLeft, /* Column expression to left of MATCH/op2 */ + Expr **ppRight /* Expression to left of MATCH/op2 */ ){ - static const struct Op2 { - const char *zOp; - unsigned char eOp2; - } aOp[] = { - { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, - { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, - { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, - { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } - }; - ExprList *pList; - Expr *pCol; /* Column reference */ - int i; + if( pExpr->op==TK_FUNCTION ){ + static const struct Op2 { + const char *zOp; + unsigned char eOp2; + } aOp[] = { + { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, + { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, + { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, + { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } + }; + ExprList *pList; + Expr *pCol; /* Column reference */ + int i; - if( pExpr->op!=TK_FUNCTION ){ - return 0; - } - pList = pExpr->x.pList; - if( pList==0 || pList->nExpr!=2 ){ - return 0; - } - pCol = pList->a[1].pExpr; - if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){ - return 0; - } - for(i=0; iu.zToken, aOp[i].zOp)==0 ){ - *peOp2 = aOp[i].eOp2; - return 1; + pList = pExpr->x.pList; + if( pList==0 || pList->nExpr!=2 ){ + return 0; } + + /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a + ** virtual table on their second argument, which is the same as + ** the left-hand side operand in their in-fix form. + ** + ** vtab_column MATCH expression + ** MATCH(expression,vtab_column) + */ + pCol = pList->a[1].pExpr; + if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + *peOp2 = aOp[i].eOp2; + *ppRight = pList->a[0].pExpr; + *ppLeft = pCol; + return 1; + } + } + } + + /* We can also match against the first column of overloaded + ** functions where xFindFunction returns a value of at least + ** SQLITE_INDEX_CONSTRAINT_FUNCTION. + ** + ** OVERLOADED(vtab_column,expression) + ** + ** Historically, xFindFunction expected to see lower-case function + ** names. But for this use case, xFindFunction is expected to deal + ** with function names in an arbitrary case. + */ + pCol = pList->a[0].pExpr; + if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); + void *pNotUsed; + pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction!=0 ){ + i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); + if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + *peOp2 = i; + *ppRight = pList->a[1].pExpr; + *ppLeft = pCol; + return 1; + } + } + } + }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ + int res = 0; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ + res++; + } + if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ + res++; + SWAP(Expr*, pLeft, pRight); + } + *ppLeft = pLeft; + *ppRight = pRight; + if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE; + if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT; + if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL; + return res; } return 0; } @@ -606,7 +690,7 @@ static void exprAnalyzeOrTerm( for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ assert( pAndTerm->pExpr ); if( allowedOp(pAndTerm->pExpr->op) - || pAndTerm->eOperator==WO_MATCH + || pAndTerm->eOperator==WO_AUX ){ b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); } @@ -638,7 +722,12 @@ static void exprAnalyzeOrTerm( ** empty. */ pOrInfo->indexable = indexable; - pTerm->eOperator = indexable==0 ? 0 : WO_OR; + if( indexable ){ + pTerm->eOperator = WO_OR; + pWC->hasOr = 1; + }else{ + pTerm->eOperator = WO_OR; + } /* For a two-way OR, attempt to implementation case 2. */ @@ -779,12 +868,11 @@ static void exprAnalyzeOrTerm( idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); exprAnalyze(pSrc, pWC, idxNew); - pTerm = &pWC->a[idxTerm]; + /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */ markTermAsChild(pWC, idxNew, idxTerm); }else{ sqlite3ExprListDelete(db, pList); } - pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */ } } } @@ -808,7 +896,6 @@ static void exprAnalyzeOrTerm( static int termIsEquivalence(Parse *pParse, Expr *pExpr){ char aff1, aff2; CollSeq *pColl; - const char *zColl1, *zColl2; if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; @@ -820,12 +907,8 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){ return 0; } pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); - if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1; - pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - zColl1 = pColl ? pColl->zName : 0; - pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight); - zColl2 = pColl ? pColl->zName : 0; - return sqlite3_stricmp(zColl1, zColl2)==0; + if( sqlite3IsBinary(pColl) ) return 1; + return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); } /* @@ -847,6 +930,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ for(i=0; inSrc; i++){ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn); + if( pSrc->a[i].fg.isTabFunc ){ + mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); + } } } pS = pS->pPrior; @@ -954,7 +1040,7 @@ static void exprAnalyze( int op; /* Top-level operator. pExpr->op */ Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection */ - unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */ + unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */ int nLeft; /* Number of elements on left side vector */ if( db->mallocFailed ){ @@ -980,7 +1066,7 @@ static void exprAnalyze( pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); } pMaskSet->bVarSelect = 0; - prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr); + prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; if( ExprHasProperty(pExpr, EP_FromJoin) ){ Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); @@ -1162,7 +1248,7 @@ static void exprAnalyze( } *pC = c + 1; } - zCollSeqName = noCase ? "NOCASE" : "BINARY"; + zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY; pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), @@ -1188,41 +1274,46 @@ static void exprAnalyze( #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ #ifndef SQLITE_OMIT_VIRTUALTABLE - /* Add a WO_MATCH auxiliary term to the constraint set if the - ** current expression is of the form: column MATCH expr. + /* Add a WO_AUX auxiliary term to the constraint set if the + ** current expression is of the form "column OP expr" where OP + ** is an operator that gets passed into virtual tables but which is + ** not normally optimized for ordinary tables. In other words, OP + ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. ** This information is used by the xBestIndex methods of ** virtual tables. The native query optimizer does not attempt ** to do anything with MATCH functions. */ - if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){ - int idxNew; - Expr *pRight, *pLeft; - WhereTerm *pNewTerm; - Bitmask prereqColumn, prereqExpr; + if( pWC->op==TK_AND ){ + Expr *pRight = 0, *pLeft = 0; + int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); + while( res-- > 0 ){ + int idxNew; + WhereTerm *pNewTerm; + Bitmask prereqColumn, prereqExpr; - pRight = pExpr->x.pList->a[0].pExpr; - pLeft = pExpr->x.pList->a[1].pExpr; - prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); - prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); - if( (prereqExpr & prereqColumn)==0 ){ - Expr *pNewExpr; - pNewExpr = sqlite3PExpr(pParse, TK_MATCH, - 0, sqlite3ExprDup(db, pRight, 0)); - if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ - ExprSetProperty(pNewExpr, EP_FromJoin); + prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); + prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); + if( (prereqExpr & prereqColumn)==0 ){ + Expr *pNewExpr; + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + 0, sqlite3ExprDup(db, pRight, 0)); + if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ + ExprSetProperty(pNewExpr, EP_FromJoin); + } + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = prereqExpr; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_AUX; + pNewTerm->eMatchOp = eOp2; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; } - idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); - testcase( idxNew==0 ); - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = prereqExpr; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_MATCH; - pNewTerm->eMatchOp = eOp2; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; + SWAP(Expr*, pLeft, pRight); } } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -1254,7 +1345,7 @@ static void exprAnalyze( exprAnalyze(pSrc, pWC, idxNew); } pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */ + pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */ pTerm->eOperator = 0; } @@ -1368,6 +1459,7 @@ void sqlite3WhereClauseInit( WhereInfo *pWInfo /* The WHERE processing context */ ){ pWC->pWInfo = pWInfo; + pWC->hasOr = 0; pWC->pOuter = 0; pWC->nTerm = 0; pWC->nSlot = ArraySize(pWC->aStatic); @@ -1404,17 +1496,18 @@ void sqlite3WhereClauseClear(WhereClause *pWC){ ** a bitmask indicating which tables are used in that expression ** tree. */ -Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ +Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ Bitmask mask; - if( p==0 ) return 0; - if( p->op==TK_COLUMN ){ + if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ return sqlite3WhereGetMask(pMaskSet, p->iTable); + }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ + assert( p->op!=TK_IF_NULL_ROW ); + return 0; } mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; - assert( !ExprHasProperty(p, EP_TokenOnly) ); - if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); + if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); if( p->pRight ){ - mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight); + mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight); assert( p->x.pList==0 ); }else if( ExprHasProperty(p, EP_xIsSelect) ){ if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; @@ -1424,6 +1517,9 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ } return mask; } +Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ + return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; +} Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ int i; Bitmask mask = 0; @@ -1487,7 +1583,7 @@ void sqlite3WhereTabFuncArgs( if( pColRef==0 ) return; pColRef->iTable = pItem->iCursor; pColRef->iColumn = k++; - pColRef->pTab = pTab; + pColRef->y.pTab = pTab; pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0)); whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); diff --git a/src/window.c b/src/window.c new file mode 100644 index 0000000000..36cfc1c280 --- /dev/null +++ b/src/window.c @@ -0,0 +1,2254 @@ +/* +** 2018 May 08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ +#include "sqliteInt.h" + +#ifndef SQLITE_OMIT_WINDOWFUNC + +/* +** SELECT REWRITING +** +** Any SELECT statement that contains one or more window functions in +** either the select list or ORDER BY clause (the only two places window +** functions may be used) is transformed by function sqlite3WindowRewrite() +** in order to support window function processing. For example, with the +** schema: +** +** CREATE TABLE t1(a, b, c, d, e, f, g); +** +** the statement: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e; +** +** is transformed to: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT a, e, c, d, b FROM t1 ORDER BY c, d +** ) ORDER BY e; +** +** The flattening optimization is disabled when processing this transformed +** SELECT statement. This allows the implementation of the window function +** (in this case max()) to process rows sorted in order of (c, d), which +** makes things easier for obvious reasons. More generally: +** +** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to +** the sub-query. +** +** * ORDER BY, LIMIT and OFFSET remain part of the parent query. +** +** * Terminals from each of the expression trees that make up the +** select-list and ORDER BY expressions in the parent query are +** selected by the sub-query. For the purposes of the transformation, +** terminals are column references and aggregate functions. +** +** If there is more than one window function in the SELECT that uses +** the same window declaration (the OVER bit), then a single scan may +** be used to process more than one window function. For example: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY c ORDER BY d) +** FROM t1; +** +** is transformed in the same way as the example above. However: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY a ORDER BY b) +** FROM t1; +** +** Must be transformed to: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM +** SELECT a, e, c, d, b FROM t1 ORDER BY a, b +** ) ORDER BY c, d +** ) ORDER BY e; +** +** so that both min() and max() may process rows in the order defined by +** their respective window declarations. +** +** INTERFACE WITH SELECT.C +** +** When processing the rewritten SELECT statement, code in select.c calls +** sqlite3WhereBegin() to begin iterating through the results of the +** sub-query, which is always implemented as a co-routine. It then calls +** sqlite3WindowCodeStep() to process rows and finish the scan by calling +** sqlite3WhereEnd(). +** +** sqlite3WindowCodeStep() generates VM code so that, for each row returned +** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked. +** When the sub-routine is invoked: +** +** * The results of all window-functions for the row are stored +** in the associated Window.regResult registers. +** +** * The required terminal values are stored in the current row of +** temp table Window.iEphCsr. +** +** In some cases, depending on the window frame and the specific window +** functions invoked, sqlite3WindowCodeStep() caches each entire partition +** in a temp table before returning any rows. In other cases it does not. +** This detail is encapsulated within this file, the code generated by +** select.c is the same in either case. +** +** BUILT-IN WINDOW FUNCTIONS +** +** This implementation features the following built-in window functions: +** +** row_number() +** rank() +** dense_rank() +** percent_rank() +** cume_dist() +** ntile(N) +** lead(expr [, offset [, default]]) +** lag(expr [, offset [, default]]) +** first_value(expr) +** last_value(expr) +** nth_value(expr, N) +** +** These are the same built-in window functions supported by Postgres. +** Although the behaviour of aggregate window functions (functions that +** can be used as either aggregates or window funtions) allows them to +** be implemented using an API, built-in window functions are much more +** esoteric. Additionally, some window functions (e.g. nth_value()) +** may only be implemented by caching the entire partition in memory. +** As such, some built-in window functions use the same API as aggregate +** window functions and some are implemented directly using VDBE +** instructions. Additionally, for those functions that use the API, the +** window frame is sometimes modified before the SELECT statement is +** rewritten. For example, regardless of the specified window frame, the +** row_number() function always uses: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** See sqlite3WindowUpdate() for details. +** +** As well as some of the built-in window functions, aggregate window +** functions min() and max() are implemented using VDBE instructions if +** the start of the window frame is declared as anything other than +** UNBOUNDED PRECEDING. +*/ + +/* +** Implementation of built-in window function row_number(). Assumes that the +** window frame has been coerced to: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void row_numberStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) (*p)++; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void row_numberValueFunc(sqlite3_context *pCtx){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + sqlite3_result_int64(pCtx, (p ? *p : 0)); +} + +/* +** Context object type used by rank(), dense_rank(), percent_rank() and +** cume_dist(). +*/ +struct CallCount { + i64 nValue; + i64 nStep; + i64 nTotal; +}; + +/* +** Implementation of built-in window function dense_rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void dense_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) p->nStep = 1; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void dense_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nStep ){ + p->nValue++; + p->nStep = 0; + } + sqlite3_result_int64(pCtx, p->nValue); + } +} + +/* +** Implementation of built-in window function rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nStep++; + if( p->nValue==0 ){ + p->nValue = p->nStep; + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + sqlite3_result_int64(pCtx, p->nValue); + p->nValue = 0; + } +} + +/* +** Implementation of built-in window function percent_rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void percent_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==1 ); + + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nTotal = sqlite3_value_int64(apArg[0]); + } + p->nStep++; + if( p->nValue==0 ){ + p->nValue = p->nStep; + } + } +} +static void percent_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal>1 ){ + double r = (double)(p->nValue-1) / (double)(p->nTotal-1); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_double(pCtx, 0.0); + } + p->nValue = 0; + } +} + +/* +** Implementation of built-in window function cume_dist(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void cume_distStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + assert( nArg==1 ); UNUSED_PARAMETER(nArg); + + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nTotal = sqlite3_value_int64(apArg[0]); + } + p->nStep++; + } +} +static void cume_distValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->nTotal ){ + double r = (double)(p->nStep) / (double)(p->nTotal); + sqlite3_result_double(pCtx, r); + } +} + +/* +** Context object for ntile() window function. +*/ +struct NtileCtx { + i64 nTotal; /* Total rows in partition */ + i64 nParam; /* Parameter passed to ntile(N) */ + i64 iRow; /* Current row */ +}; + +/* +** Implementation of ntile(). This assumes that the window frame has +** been coerced to: +** +** ROWS UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void ntileStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NtileCtx *p; + assert( nArg==2 ); UNUSED_PARAMETER(nArg); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nParam = sqlite3_value_int64(apArg[0]); + p->nTotal = sqlite3_value_int64(apArg[1]); + if( p->nParam<=0 ){ + sqlite3_result_error( + pCtx, "argument of ntile must be a positive integer", -1 + ); + } + } + p->iRow++; + } +} +static void ntileValueFunc(sqlite3_context *pCtx){ + struct NtileCtx *p; + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->nParam>0 ){ + int nSize = (p->nTotal / p->nParam); + if( nSize==0 ){ + sqlite3_result_int64(pCtx, p->iRow); + }else{ + i64 nLarge = p->nTotal - p->nParam*nSize; + i64 iSmall = nLarge*(nSize+1); + i64 iRow = p->iRow-1; + + assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal ); + + if( iRowpVal); + p->pVal = sqlite3_value_dup(apArg[0]); + if( p->pVal==0 ){ + sqlite3_result_error_nomem(pCtx); + }else{ + p->nVal++; + } + } +} +static void last_valueInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct LastValueCtx *p; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( ALWAYS(p) ){ + p->nVal--; + if( p->nVal==0 ){ + sqlite3_value_free(p->pVal); + p->pVal = 0; + } + } +} +static void last_valueValueFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + } +} +static void last_valueFinalizeFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + sqlite3_value_free(p->pVal); + p->pVal = 0; + } +} + +/* +** Static names for the built-in window function names. These static +** names are used, rather than string literals, so that FuncDef objects +** can be associated with a particular window function by direct +** comparison of the zName pointer. Example: +** +** if( pFuncDef->zName==row_valueName ){ ... } +*/ +static const char row_numberName[] = "row_number"; +static const char dense_rankName[] = "dense_rank"; +static const char rankName[] = "rank"; +static const char percent_rankName[] = "percent_rank"; +static const char cume_distName[] = "cume_dist"; +static const char ntileName[] = "ntile"; +static const char last_valueName[] = "last_value"; +static const char nth_valueName[] = "nth_value"; +static const char first_valueName[] = "first_value"; +static const char leadName[] = "lead"; +static const char lagName[] = "lag"; + +/* +** No-op implementations of xStep() and xFinalize(). Used as place-holders +** for built-in window functions that never call those interfaces. +** +** The noopValueFunc() is called but is expected to do nothing. The +** noopStepFunc() is never called, and so it is marked with NO_TEST to +** let the test coverage routine know not to expect this function to be +** invoked. +*/ +static void noopStepFunc( /*NO_TEST*/ + sqlite3_context *p, /*NO_TEST*/ + int n, /*NO_TEST*/ + sqlite3_value **a /*NO_TEST*/ +){ /*NO_TEST*/ + UNUSED_PARAMETER(p); /*NO_TEST*/ + UNUSED_PARAMETER(n); /*NO_TEST*/ + UNUSED_PARAMETER(a); /*NO_TEST*/ + assert(0); /*NO_TEST*/ +} /*NO_TEST*/ +static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } + +/* Window functions that use all window interfaces: xStep, xFinal, +** xValue, and xInverse */ +#define WINDOWFUNCALL(name,nArg,extra) { \ + nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \ + name ## InvFunc, name ## Name, {0} \ +} + +/* Window functions that are implemented using bytecode and thus have +** no-op routines for their methods */ +#define WINDOWFUNCNOOP(name,nArg,extra) { \ + nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + noopStepFunc, noopValueFunc, noopValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + +/* Window functions that use all window interfaces: xStep, the +** same routine for xFinalize and xValue and which never call +** xInverse. */ +#define WINDOWFUNCX(name,nArg,extra) { \ + nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + + +/* +** Register those built-in window functions that are not also aggregates. +*/ +void sqlite3WindowFunctions(void){ + static FuncDef aWindowFuncs[] = { + WINDOWFUNCX(row_number, 0, 0), + WINDOWFUNCX(dense_rank, 0, 0), + WINDOWFUNCX(rank, 0, 0), + WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE), + WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE), + WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE), + WINDOWFUNCALL(last_value, 1, 0), + WINDOWFUNCNOOP(nth_value, 2, 0), + WINDOWFUNCNOOP(first_value, 1, 0), + WINDOWFUNCNOOP(lead, 1, 0), + WINDOWFUNCNOOP(lead, 2, 0), + WINDOWFUNCNOOP(lead, 3, 0), + WINDOWFUNCNOOP(lag, 1, 0), + WINDOWFUNCNOOP(lag, 2, 0), + WINDOWFUNCNOOP(lag, 3, 0), + }; + sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs)); +} + +/* +** This function is called immediately after resolving the function name +** for a window function within a SELECT statement. Argument pList is a +** linked list of WINDOW definitions for the current SELECT statement. +** Argument pFunc is the function definition just resolved and pWin +** is the Window object representing the associated OVER clause. This +** function updates the contents of pWin as follows: +** +** * If the OVER clause refered to a named window (as in "max(x) OVER win"), +** search list pList for a matching WINDOW definition, and update pWin +** accordingly. If no such WINDOW clause can be found, leave an error +** in pParse. +** +** * If the function is a built-in window function that requires the +** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top +** of this file), pWin is updated here. +*/ +void sqlite3WindowUpdate( + Parse *pParse, + Window *pList, /* List of named windows for this SELECT */ + Window *pWin, /* Window frame to update */ + FuncDef *pFunc /* Window function definition */ +){ + if( pWin->zName && pWin->eType==0 ){ + Window *p; + for(p=pList; p; p=p->pNextWin){ + if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break; + } + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName); + return; + } + pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0); + pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0); + pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0); + pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); + pWin->eStart = p->eStart; + pWin->eEnd = p->eEnd; + pWin->eType = p->eType; + } + if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ + sqlite3 *db = pParse->db; + if( pWin->pFilter ){ + sqlite3ErrorMsg(pParse, + "FILTER clause may only be used with aggregate window functions" + ); + }else + if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){ + sqlite3ExprDelete(db, pWin->pStart); + sqlite3ExprDelete(db, pWin->pEnd); + pWin->pStart = pWin->pEnd = 0; + pWin->eType = TK_ROWS; + pWin->eStart = TK_UNBOUNDED; + pWin->eEnd = TK_CURRENT; + }else + + if( pFunc->zName==dense_rankName || pFunc->zName==rankName + || pFunc->zName==percent_rankName || pFunc->zName==cume_distName + ){ + sqlite3ExprDelete(db, pWin->pStart); + sqlite3ExprDelete(db, pWin->pEnd); + pWin->pStart = pWin->pEnd = 0; + pWin->eType = TK_RANGE; + pWin->eStart = TK_UNBOUNDED; + pWin->eEnd = TK_CURRENT; + } + } + pWin->pFunc = pFunc; +} + +/* +** Context object passed through sqlite3WalkExprList() to +** selectWindowRewriteExprCb() by selectWindowRewriteEList(). +*/ +typedef struct WindowRewrite WindowRewrite; +struct WindowRewrite { + Window *pWin; + SrcList *pSrc; + ExprList *pSub; + Select *pSubSelect; /* Current sub-select, if any */ +}; + +/* +** Callback function used by selectWindowRewriteEList(). If necessary, +** this function appends to the output expression-list and updates +** expression (*ppExpr) in place. +*/ +static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Parse *pParse = pWalker->pParse; + + /* If this function is being called from within a scalar sub-select + ** that used by the SELECT statement being processed, only process + ** TK_COLUMN expressions that refer to it (the outer SELECT). Do + ** not process aggregates or window functions at all, as they belong + ** to the scalar sub-select. */ + if( p->pSubSelect ){ + if( pExpr->op!=TK_COLUMN ){ + return WRC_Continue; + }else{ + int nSrc = p->pSrc->nSrc; + int i; + for(i=0; iiTable==p->pSrc->a[i].iCursor ) break; + } + if( i==nSrc ) return WRC_Continue; + } + } + + switch( pExpr->op ){ + + case TK_FUNCTION: + if( !ExprHasProperty(pExpr, EP_WinFunc) ){ + break; + }else{ + Window *pWin; + for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){ + if( pExpr->y.pWin==pWin ){ + assert( pWin->pOwner==pExpr ); + return WRC_Prune; + } + } + } + /* Fall through. */ + + case TK_AGG_FUNCTION: + case TK_COLUMN: { + Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); + p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); + if( p->pSub ){ + assert( ExprHasProperty(pExpr, EP_Static)==0 ); + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(pParse->db, pExpr); + ExprClearProperty(pExpr, EP_Static); + memset(pExpr, 0, sizeof(Expr)); + + pExpr->op = TK_COLUMN; + pExpr->iColumn = p->pSub->nExpr-1; + pExpr->iTable = p->pWin->iEphCsr; + } + + break; + } + + default: /* no-op */ + break; + } + + return WRC_Continue; +} +static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Select *pSave = p->pSubSelect; + if( pSave==pSelect ){ + return WRC_Continue; + }else{ + p->pSubSelect = pSelect; + sqlite3WalkSelect(pWalker, pSelect); + p->pSubSelect = pSave; + } + return WRC_Prune; +} + + +/* +** Iterate through each expression in expression-list pEList. For each: +** +** * TK_COLUMN, +** * aggregate function, or +** * window function with a Window object that is not a member of the +** Window list passed as the second argument (pWin). +** +** Append the node to output expression-list (*ppSub). And replace it +** with a TK_COLUMN that reads the (N-1)th element of table +** pWin->iEphCsr, where N is the number of elements in (*ppSub) after +** appending the new one. +*/ +static void selectWindowRewriteEList( + Parse *pParse, + Window *pWin, + SrcList *pSrc, + ExprList *pEList, /* Rewrite expressions in this list */ + ExprList **ppSub /* IN/OUT: Sub-select expression-list */ +){ + Walker sWalker; + WindowRewrite sRewrite; + + memset(&sWalker, 0, sizeof(Walker)); + memset(&sRewrite, 0, sizeof(WindowRewrite)); + + sRewrite.pSub = *ppSub; + sRewrite.pWin = pWin; + sRewrite.pSrc = pSrc; + + sWalker.pParse = pParse; + sWalker.xExprCallback = selectWindowRewriteExprCb; + sWalker.xSelectCallback = selectWindowRewriteSelectCb; + sWalker.u.pRewrite = &sRewrite; + + (void)sqlite3WalkExprList(&sWalker, pEList); + + *ppSub = sRewrite.pSub; +} + +/* +** Append a copy of each expression in expression-list pAppend to +** expression list pList. Return a pointer to the result list. +*/ +static ExprList *exprListAppendList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + ExprList *pAppend /* List of values to append. Might be NULL */ +){ + if( pAppend ){ + int i; + int nInit = pList ? pList->nExpr : 0; + for(i=0; inExpr; i++){ + Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); + pList = sqlite3ExprListAppend(pParse, pList, pDup); + if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder; + } + } + return pList; +} + +/* +** If the SELECT statement passed as the second argument does not invoke +** any SQL window functions, this function is a no-op. Otherwise, it +** rewrites the SELECT statement so that window function xStep functions +** are invoked in the correct order as described under "SELECT REWRITING" +** at the top of this file. +*/ +int sqlite3WindowRewrite(Parse *pParse, Select *p){ + int rc = SQLITE_OK; + if( p->pWin ){ + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3 *db = pParse->db; + Select *pSub = 0; /* The subquery */ + SrcList *pSrc = p->pSrc; + Expr *pWhere = p->pWhere; + ExprList *pGroupBy = p->pGroupBy; + Expr *pHaving = p->pHaving; + ExprList *pSort = 0; + + ExprList *pSublist = 0; /* Expression list for sub-query */ + Window *pMWin = p->pWin; /* Master window object */ + Window *pWin; /* Window object iterator */ + + p->pSrc = 0; + p->pWhere = 0; + p->pGroupBy = 0; + p->pHaving = 0; + + /* Create the ORDER BY clause for the sub-select. This is the concatenation + ** of the window PARTITION and ORDER BY clauses. Then, if this makes it + ** redundant, remove the ORDER BY from the parent SELECT. */ + pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0); + pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy); + if( pSort && p->pOrderBy ){ + if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ + sqlite3ExprListDelete(db, p->pOrderBy); + p->pOrderBy = 0; + } + } + + /* Assign a cursor number for the ephemeral table used to buffer rows. + ** The OpenEphemeral instruction is coded later, after it is known how + ** many columns the table will have. */ + pMWin->iEphCsr = pParse->nTab++; + + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist); + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist); + pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0); + + /* Append the PARTITION BY and ORDER BY expressions to the to the + ** sub-select expression list. They are required to figure out where + ** boundaries for partitions and sets of peer rows lie. */ + pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition); + pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy); + + /* Append the arguments passed to each window function to the + ** sub-select expression list. Also allocate two registers for each + ** window function - one for the accumulator, another for interim + ** results. */ + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList); + if( pWin->pFilter ){ + Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); + pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); + } + pWin->regAccum = ++pParse->nMem; + pWin->regResult = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + } + + /* If there is no ORDER BY or PARTITION BY clause, and the window + ** function accepts zero arguments, and there are no other columns + ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible + ** that pSublist is still NULL here. Add a constant expression here to + ** keep everything legal in this case. + */ + if( pSublist==0 ){ + pSublist = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0) + ); + } + + pSub = sqlite3SelectNew( + pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 + ); + p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + assert( p->pSrc || db->mallocFailed ); + if( p->pSrc ){ + p->pSrc->a[0].pSelect = pSub; + sqlite3SrcListAssignCursors(pParse, p->pSrc); + if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){ + rc = SQLITE_NOMEM; + }else{ + pSub->selFlags |= SF_Expanded; + p->selFlags &= ~SF_Aggregate; + sqlite3SelectPrep(pParse, pSub, 0); + } + + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr); + }else{ + sqlite3SelectDelete(db, pSub); + } + if( db->mallocFailed ) rc = SQLITE_NOMEM; + } + + return rc; +} + +/* +** Free the Window object passed as the second argument. +*/ +void sqlite3WindowDelete(sqlite3 *db, Window *p){ + if( p ){ + sqlite3ExprDelete(db, p->pFilter); + sqlite3ExprListDelete(db, p->pPartition); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pEnd); + sqlite3ExprDelete(db, p->pStart); + sqlite3DbFree(db, p->zName); + sqlite3DbFree(db, p); + } +} + +/* +** Free the linked list of Window objects starting at the second argument. +*/ +void sqlite3WindowListDelete(sqlite3 *db, Window *p){ + while( p ){ + Window *pNext = p->pNextWin; + sqlite3WindowDelete(db, p); + p = pNext; + } +} + +/* +** The argument expression is an PRECEDING or FOLLOWING offset. The +** value should be a non-negative integer. If the value is not a +** constant, change it to NULL. The fact that it is then a non-negative +** integer will be caught later. But it is important not to leave +** variable values in the expression tree. +*/ +static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ + if( 0==sqlite3ExprIsConstant(pExpr) ){ + sqlite3ExprDelete(pParse->db, pExpr); + pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); + } + return pExpr; +} + +/* +** Allocate and return a new Window object describing a Window Definition. +*/ +Window *sqlite3WindowAlloc( + Parse *pParse, /* Parsing context */ + int eType, /* Frame type. TK_RANGE or TK_ROWS */ + int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */ + Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */ + int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */ + Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */ +){ + Window *pWin = 0; + + /* Parser assures the following: */ + assert( eType==TK_RANGE || eType==TK_ROWS ); + assert( eStart==TK_CURRENT || eStart==TK_PRECEDING + || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING ); + assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING + || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING ); + assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) ); + assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) ); + + + /* If a frame is declared "RANGE" (not "ROWS"), then it may not use + ** either " PRECEDING" or " FOLLOWING". + */ + if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){ + sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW"); + goto windowAllocErr; + } + + /* Additionally, the + ** starting boundary type may not occur earlier in the following list than + ** the ending boundary type: + ** + ** UNBOUNDED PRECEDING + ** PRECEDING + ** CURRENT ROW + ** FOLLOWING + ** UNBOUNDED FOLLOWING + ** + ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending + ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting + ** frame boundary. + */ + if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING) + || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT)) + ){ + sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS"); + goto windowAllocErr; + } + + pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( pWin==0 ) goto windowAllocErr; + pWin->eType = eType; + pWin->eStart = eStart; + pWin->eEnd = eEnd; + pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd); + pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart); + return pWin; + +windowAllocErr: + sqlite3ExprDelete(pParse->db, pEnd); + sqlite3ExprDelete(pParse->db, pStart); + return 0; +} + +/* +** Attach window object pWin to expression p. +*/ +void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ + if( p ){ + assert( p->op==TK_FUNCTION ); + /* This routine is only called for the parser. If pWin was not + ** allocated due to an OOM, then the parser would fail before ever + ** invoking this routine */ + if( ALWAYS(pWin) ){ + p->y.pWin = pWin; + ExprSetProperty(p, EP_WinFunc); + pWin->pOwner = p; + if( p->flags & EP_Distinct ){ + sqlite3ErrorMsg(pParse, + "DISTINCT is not supported for window functions"); + } + } + }else{ + sqlite3WindowDelete(pParse->db, pWin); + } +} + +/* +** Return 0 if the two window objects are identical, or non-zero otherwise. +** Identical window objects can be processed in a single scan. +*/ +int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){ + if( p1->eType!=p2->eType ) return 1; + if( p1->eStart!=p2->eStart ) return 1; + if( p1->eEnd!=p2->eEnd ) return 1; + if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; + if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; + if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1; + if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1; + return 0; +} + + +/* +** This is called by code in select.c before it calls sqlite3WhereBegin() +** to begin iterating through the sub-query results. It is used to allocate +** and initialize registers and cursors used by sqlite3WindowCodeStep(). +*/ +void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){ + Window *pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0); + nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); + if( nPart ){ + pMWin->regPart = pParse->nMem+1; + pParse->nMem += nPart; + sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1); + } + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *p = pWin->pFunc; + if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){ + /* The inline versions of min() and max() require a single ephemeral + ** table and 3 registers. The registers are used as follows: + ** + ** regApp+0: slot to copy min()/max() argument to for MakeRecord + ** regApp+1: integer value used to ensure keys are unique + ** regApp+2: output of MakeRecord + */ + ExprList *pList = pWin->pOwner->x.pList; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); + pWin->csrApp = pParse->nTab++; + pWin->regApp = pParse->nMem+1; + pParse->nMem += 3; + if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){ + assert( pKeyInfo->aSortOrder[0]==0 ); + pKeyInfo->aSortOrder[0] = 1; + } + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); + sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + else if( p->zName==nth_valueName || p->zName==first_valueName ){ + /* Allocate two registers at pWin->regApp. These will be used to + ** store the start and end index of the current frame. */ + assert( pMWin->iEphCsr ); + pWin->regApp = pParse->nMem+1; + pWin->csrApp = pParse->nTab++; + pParse->nMem += 2; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + else if( p->zName==leadName || p->zName==lagName ){ + assert( pMWin->iEphCsr ); + pWin->csrApp = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + } +} + +/* +** A "PRECEDING " (eCond==0) or "FOLLOWING " (eCond==1) or the +** value of the second argument to nth_value() (eCond==2) has just been +** evaluated and the result left in register reg. This function generates VM +** code to check that the value is a non-negative integer and throws an +** exception if it is not. +*/ +static void windowCheckIntValue(Parse *pParse, int reg, int eCond){ + static const char *azErr[] = { + "frame starting offset must be a non-negative integer", + "frame ending offset must be a non-negative integer", + "second argument to nth_value must be a positive integer" + }; + static int aOp[] = { OP_Ge, OP_Ge, OP_Gt }; + Vdbe *v = sqlite3GetVdbe(pParse); + int regZero = sqlite3GetTempReg(pParse); + assert( eCond==0 || eCond==1 || eCond==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero); + sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverageIf(v, eCond==0); + VdbeCoverageIf(v, eCond==1); + VdbeCoverageIf(v, eCond==2); + sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); + VdbeCoverageNeverNullIf(v, eCond==0); + VdbeCoverageNeverNullIf(v, eCond==1); + VdbeCoverageNeverNullIf(v, eCond==2); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); + sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); + sqlite3ReleaseTempReg(pParse, regZero); +} + +/* +** Return the number of arguments passed to the window-function associated +** with the object passed as the only argument to this function. +*/ +static int windowArgCount(Window *pWin){ + ExprList *pList = pWin->pOwner->x.pList; + return (pList ? pList->nExpr : 0); +} + +/* +** Generate VM code to invoke either xStep() (if bInverse is 0) or +** xInverse (if bInverse is non-zero) for each window function in the +** linked list starting at pMWin. Or, for built-in window functions +** that do not use the standard function API, generate the required +** inline VM code. +** +** If argument csr is greater than or equal to 0, then argument reg is +** the first register in an array of registers guaranteed to be large +** enough to hold the array of arguments for each function. In this case +** the arguments are extracted from the current row of csr into the +** array of registers before invoking OP_AggStep or OP_AggInverse +** +** Or, if csr is less than zero, then the array of registers at reg is +** already populated with all columns from the current row of the sub-query. +** +** If argument regPartSize is non-zero, then it is a register containing the +** number of rows in the current partition. +*/ +static void windowAggStep( + Parse *pParse, + Window *pMWin, /* Linked list of window functions */ + int csr, /* Read arguments from this cursor */ + int bInverse, /* True to invoke xInverse instead of xStep */ + int reg, /* Array of registers */ + int regPartSize /* Register containing size of partition */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + int flags = pWin->pFunc->funcFlags; + int regArg; + int nArg = windowArgCount(pWin); + + if( csr>=0 ){ + int i; + for(i=0; iiArgCol+i, reg+i); + } + regArg = reg; + if( flags & SQLITE_FUNC_WINDOW_SIZE ){ + if( nArg==0 ){ + regArg = regPartSize; + }else{ + sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg); + } + nArg++; + } + }else{ + assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) ); + regArg = reg + pWin->iArgCol; + } + + if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) + && pWin->eStart!=TK_UNBOUNDED + ){ + int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg); + VdbeCoverage(v); + if( bInverse==0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2); + }else{ + sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + } + sqlite3VdbeJumpHere(v, addrIsNull); + }else if( pWin->regApp ){ + assert( pWin->pFunc->zName==nth_valueName + || pWin->pFunc->zName==first_valueName + ); + assert( bInverse==0 || bInverse==1 ); + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); + }else if( pWin->pFunc->zName==leadName + || pWin->pFunc->zName==lagName + ){ + /* no-op */ + }else{ + int addrIf = 0; + if( pWin->pFilter ){ + int regTmp; + assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr ); + assert( nArg || pWin->pOwner->x.pList==0 ); + if( csr>0 ){ + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + }else{ + regTmp = regArg + nArg; + } + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + if( csr>0 ){ + sqlite3ReleaseTempReg(pParse, regTmp); + } + } + if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl; + assert( nArg>0 ); + pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); + sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, + bInverse, regArg, pWin->regAccum); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); + } + } +} + +/* +** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize() +** (bFinal==1) for each window function in the linked list starting at +** pMWin. Or, for built-in window-functions that do not use the standard +** API, generate the equivalent VM code. +*/ +static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){ + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) + && pWin->eStart!=TK_UNBOUNDED + ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + if( bFinal ){ + sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); + } + }else if( pWin->regApp ){ + }else{ + if( bFinal ){ + sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin)); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + }else{ + sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin), + pWin->regResult); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + } + } + } +} + +/* +** This function generates VM code to invoke the sub-routine at address +** lblFlushPart once for each partition with the entire partition cached in +** the Window.iEphCsr temp table. +*/ +static void windowPartitionCache( + Parse *pParse, + Select *p, /* The rewritten SELECT statement */ + WhereInfo *pWInfo, /* WhereInfo to call WhereEnd() on */ + int regFlushPart, /* Register to use with Gosub lblFlushPart */ + int lblFlushPart, /* Subroutine to Gosub to */ + int *pRegSize /* OUT: Register containing partition size */ +){ + Window *pMWin = p->pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int iSubCsr = p->pSrc->a[0].iCursor; + int nSub = p->pSrc->a[0].pTab->nCol; + int k; + + int reg = pParse->nMem+1; + int regRecord = reg+nSub; + int regRowid = regRecord+1; + + *pRegSize = regRowid; + pParse->nMem += nSub + 2; + + /* Load the column values for the row returned by the sub-select + ** into an array of registers starting at reg. */ + for(k=0; kpPartition ){ + int addr; + ExprList *pPart = pMWin->pPartition; + int nPart = pPart->nExpr; + int regNewPart = reg + pMWin->nBufferCol; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); + + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2); + VdbeCoverageEqNe(v); + sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1); + sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart); + VdbeComment((v, "call flush_partition")); + } + + /* Buffer the current row in the ephemeral table. */ + sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid); + + /* End of the input loop */ + sqlite3WhereEnd(pWInfo); + + /* Invoke "flush_partition" to deal with the final (or only) partition */ + sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart); + VdbeComment((v, "call flush_partition")); +} + +/* +** Invoke the sub-routine at regGosub (generated by code in select.c) to +** return the current row of Window.iEphCsr. If all window functions are +** aggregate window functions that use the standard API, a single +** OP_Gosub instruction is all that this routine generates. Extra VM code +** for per-row processing is only generated for the following built-in window +** functions: +** +** nth_value() +** first_value() +** lag() +** lead() +*/ +static void windowReturnOneRow( + Parse *pParse, + Window *pMWin, + int regGosub, + int addrGosub +){ + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pFunc; + if( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ){ + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(v); + int tmpReg = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + + if( pFunc->zName==nth_valueName ){ + sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg); + windowCheckIntValue(pParse, tmpReg, 2); + }else{ + sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg); + } + sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg); + sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + else if( pFunc->zName==leadName || pFunc->zName==lagName ){ + int nArg = pWin->pOwner->x.pList->nExpr; + int iEph = pMWin->iEphCsr; + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(v); + int tmpReg = sqlite3GetTempReg(pParse); + + if( nArg<3 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult); + } + sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg); + if( nArg<2 ){ + int val = (pFunc->zName==leadName ? 1 : -1); + sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val); + }else{ + int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract); + int tmpReg2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2); + sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); + sqlite3ReleaseTempReg(pParse, tmpReg2); + } + + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + } + sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); +} + +/* +** Invoke the code generated by windowReturnOneRow() and, optionally, the +** xInverse() function for each window function, for one or more rows +** from the Window.iEphCsr temp table. This routine generates VM code +** similar to: +** +** while( regCtr>0 ){ +** regCtr--; +** windowReturnOneRow() +** if( bInverse ){ +** AggInverse +** } +** Next (Window.iEphCsr) +** } +*/ +static void windowReturnRows( + Parse *pParse, + Window *pMWin, /* List of window functions */ + int regCtr, /* Register containing number of rows */ + int regGosub, /* Register for Gosub addrGosub */ + int addrGosub, /* Address of sub-routine for ReturnOneRow */ + int regInvArg, /* Array of registers for xInverse args */ + int regInvSize /* Register containing size of partition */ +){ + int addr; + Vdbe *v = sqlite3GetVdbe(pParse); + windowAggFinal(pParse, pMWin, 0); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + windowReturnOneRow(pParse, pMWin, regGosub, addrGosub); + if( regInvArg ){ + windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize); + } + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */ +} + +/* +** Generate code to set the accumulator register for each window function +** in the linked list passed as the second argument to NULL. And perform +** any equivalent initialization required by any built-in window functions +** in the list. +*/ +static int windowInitAccum(Parse *pParse, Window *pMWin){ + Vdbe *v = sqlite3GetVdbe(pParse); + int regArg; + int nArg = 0; + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pFunc; + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + nArg = MAX(nArg, windowArgCount(pWin)); + if( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + + if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){ + assert( pWin->eStart!=TK_UNBOUNDED ); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + } + regArg = pParse->nMem+1; + pParse->nMem += nArg; + return regArg; +} + + +/* +** This function does the work of sqlite3WindowCodeStep() for all "ROWS" +** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT +** ROW". Pseudo-code for each follows. +** +** ROWS BETWEEN PRECEDING AND FOLLOWING +** +** ... +** if( new partition ){ +** Gosub flush_partition +** } +** Insert (record in eph-table) +** sqlite3WhereEnd() +** Gosub flush_partition +** +** flush_partition: +** Once { +** OpenDup (iEphCsr -> csrStart) +** OpenDup (iEphCsr -> csrEnd) +** } +** regStart = // PRECEDING expression +** regEnd = // FOLLOWING expression +** if( regStart<0 || regEnd<0 ){ error! } +** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done +** Next(csrEnd) // if EOF skip Aggstep +** Aggstep (csrEnd) +** if( (regEnd--)<=0 ){ +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( (regStart--)<=0 ){ +** AggInverse (csrStart) +** Next(csrStart) +** } +** } +** flush_partition_done: +** ResetSorter (csr) +** Return +** +** ROWS BETWEEN PRECEDING AND CURRENT ROW +** ROWS BETWEEN CURRENT ROW AND FOLLOWING +** ROWS BETWEEN UNBOUNDED PRECEDING AND FOLLOWING +** +** These are similar to the above. For "CURRENT ROW", intialize the +** register to 0. For "UNBOUNDED PRECEDING" to infinity. +** +** ROWS BETWEEN PRECEDING AND UNBOUNDED FOLLOWING +** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +** +** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done +** while( 1 ){ +** Next(csrEnd) // Exit while(1) at EOF +** Aggstep (csrEnd) +** } +** while( 1 ){ +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( (regStart--)<=0 ){ +** AggInverse (csrStart) +** Next(csrStart) +** } +** } +** +** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() +** condition is always true (as if regStart were initialized to 0). +** +** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +** +** This is the only RANGE case handled by this routine. It modifies the +** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to +** be: +** +** while( 1 ){ +** AggFinal (xValue) +** while( 1 ){ +** regPeer++ +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( new peer ) break; +** } +** while( (regPeer--)>0 ){ +** AggInverse (csrStart) +** Next(csrStart) +** } +** } +** +** ROWS BETWEEN FOLLOWING AND FOLLOWING +** +** regEnd = regEnd - regStart +** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done +** Aggstep (csrEnd) +** Next(csrEnd) // if EOF fall-through +** if( (regEnd--)<=0 ){ +** if( (regStart--)<=0 ){ +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** } +** AggInverse (csrStart) +** Next (csrStart) +** } +** +** ROWS BETWEEN PRECEDING AND PRECEDING +** +** Replace the bit after "Rewind" in the above with: +** +** if( (regEnd--)<=0 ){ +** AggStep (csrEnd) +** Next (csrEnd) +** } +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( (regStart--)<=0 ){ +** AggInverse (csr2) +** Next (csr2) +** } +** +*/ +static void windowCodeRowExprStep( + Parse *pParse, + Select *p, + WhereInfo *pWInfo, + int regGosub, + int addrGosub +){ + Window *pMWin = p->pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int regFlushPart; /* Register for "Gosub flush_partition" */ + int lblFlushPart; /* Label for "Gosub flush_partition" */ + int lblFlushDone; /* Label for "Gosub flush_partition_done" */ + + int regArg; + int addr; + int csrStart = pParse->nTab++; + int csrEnd = pParse->nTab++; + int regStart; /* Value of PRECEDING */ + int regEnd; /* Value of FOLLOWING */ + int addrGoto; + int addrTop; + int addrIfPos1 = 0; + int addrIfPos2 = 0; + int regSize = 0; + + assert( pMWin->eStart==TK_PRECEDING + || pMWin->eStart==TK_CURRENT + || pMWin->eStart==TK_FOLLOWING + || pMWin->eStart==TK_UNBOUNDED + ); + assert( pMWin->eEnd==TK_FOLLOWING + || pMWin->eEnd==TK_CURRENT + || pMWin->eEnd==TK_UNBOUNDED + || pMWin->eEnd==TK_PRECEDING + ); + + /* Allocate register and label for the "flush_partition" sub-routine. */ + regFlushPart = ++pParse->nMem; + lblFlushPart = sqlite3VdbeMakeLabel(v); + lblFlushDone = sqlite3VdbeMakeLabel(v); + + regStart = ++pParse->nMem; + regEnd = ++pParse->nMem; + + windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size); + + addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); + + /* Start of "flush_partition" */ + sqlite3VdbeResolveLabel(v, lblFlushPart); + sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3); + VdbeCoverage(v); + VdbeComment((v, "Flush_partition subroutine")); + sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr); + + /* If either regStart or regEnd are not non-negative integers, throw + ** an exception. */ + if( pMWin->pStart ){ + sqlite3ExprCode(pParse, pMWin->pStart, regStart); + windowCheckIntValue(pParse, regStart, 0); + } + if( pMWin->pEnd ){ + sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); + windowCheckIntValue(pParse, regEnd, 1); + } + + /* If this is "ROWS FOLLOWING AND ROWS FOLLOWING", do: + ** + ** if( regEndpEnd && pMWin->eStart==TK_FOLLOWING ){ + assert( pMWin->pStart!=0 ); + assert( pMWin->eEnd==TK_FOLLOWING ); + sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); + sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd); + } + + if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){ + assert( pMWin->pEnd!=0 ); + assert( pMWin->eStart==TK_PRECEDING ); + sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); + sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd); + } + + /* Initialize the accumulator register for each window function to NULL */ + regArg = windowInitAccum(pParse, pMWin); + + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone); + VdbeCoverageNeverTaken(v); + sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone); + VdbeCoverageNeverTaken(v); + sqlite3VdbeChangeP5(v, 1); + + /* Invoke AggStep function for each window function using the row that + ** csrEnd currently points to. Or, if csrEnd is already at EOF, + ** do nothing. */ + addrTop = sqlite3VdbeCurrentAddr(v); + if( pMWin->eEnd==TK_PRECEDING ){ + addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); + VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + addr = sqlite3VdbeAddOp0(v, OP_Goto); + windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize); + if( pMWin->eEnd==TK_UNBOUNDED ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + sqlite3VdbeJumpHere(v, addr); + addrTop = sqlite3VdbeCurrentAddr(v); + }else{ + sqlite3VdbeJumpHere(v, addr); + if( pMWin->eEnd==TK_PRECEDING ){ + sqlite3VdbeJumpHere(v, addrIfPos1); + } + } + + if( pMWin->eEnd==TK_FOLLOWING ){ + addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); + VdbeCoverage(v); + } + if( pMWin->eStart==TK_FOLLOWING ){ + addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1); + VdbeCoverage(v); + } + windowAggFinal(pParse, pMWin, 0); + windowReturnOneRow(pParse, pMWin, regGosub, addrGosub); + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone); + if( pMWin->eStart==TK_FOLLOWING ){ + sqlite3VdbeJumpHere(v, addrIfPos2); + } + + if( pMWin->eStart==TK_CURRENT + || pMWin->eStart==TK_PRECEDING + || pMWin->eStart==TK_FOLLOWING + ){ + int lblSkipInverse = sqlite3VdbeMakeLabel(v);; + if( pMWin->eStart==TK_PRECEDING ){ + sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1); + VdbeCoverage(v); + } + if( pMWin->eStart==TK_FOLLOWING ){ + sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1); + VdbeCoverageAlwaysTaken(v); + } + windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize); + sqlite3VdbeResolveLabel(v, lblSkipInverse); + } + if( pMWin->eEnd==TK_FOLLOWING ){ + sqlite3VdbeJumpHere(v, addrIfPos1); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + + /* flush_partition_done: */ + sqlite3VdbeResolveLabel(v, lblFlushDone); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); + sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); + VdbeComment((v, "end flush_partition subroutine")); + + /* Jump to here to skip over flush_partition */ + sqlite3VdbeJumpHere(v, addrGoto); +} + +/* +** This function does the work of sqlite3WindowCodeStep() for cases that +** would normally be handled by windowCodeDefaultStep() when there are +** one or more built-in window-functions that require the entire partition +** to be cached in a temp table before any rows can be returned. Additionally. +** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by +** this function. +** +** Pseudo-code corresponding to the VM code generated by this function +** for each type of window follows. +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** flush_partition: +** Once { +** OpenDup (iEphCsr -> csrLead) +** } +** Integer ctr 0 +** foreach row (csrLead){ +** if( new peer ){ +** AggFinal (xValue) +** for(i=0; i csrLead) +** } +** foreach row (csrLead) { +** AggStep (csrLead) +** } +** foreach row (iEphCsr) { +** Gosub addrGosub +** } +** +** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +** +** flush_partition: +** Once { +** OpenDup (iEphCsr -> csrLead) +** } +** foreach row (csrLead){ +** AggStep (csrLead) +** } +** Rewind (csrLead) +** Integer ctr 0 +** foreach row (csrLead){ +** if( new peer ){ +** AggFinal (xValue) +** for(i=0; ipWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int k; + int addr; + ExprList *pPart = pMWin->pPartition; + ExprList *pOrderBy = pMWin->pOrderBy; + int nPeer = pOrderBy ? pOrderBy->nExpr : 0; + int regNewPeer; + + int addrGoto; /* Address of Goto used to jump flush_par.. */ + int addrNext; /* Jump here for next iteration of loop */ + int regFlushPart; + int lblFlushPart; + int csrLead; + int regCtr; + int regArg; /* Register array to martial function args */ + int regSize; + int lblEmpty; + int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT + && pMWin->eEnd==TK_UNBOUNDED; + + assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) + ); + + lblEmpty = sqlite3VdbeMakeLabel(v); + regNewPeer = pParse->nMem+1; + pParse->nMem += nPeer; + + /* Allocate register and label for the "flush_partition" sub-routine. */ + regFlushPart = ++pParse->nMem; + lblFlushPart = sqlite3VdbeMakeLabel(v); + + csrLead = pParse->nTab++; + regCtr = ++pParse->nMem; + + windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size); + addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); + + /* Start of "flush_partition" */ + sqlite3VdbeResolveLabel(v, lblFlushPart); + sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr); + + /* Initialize the accumulator register for each window function to NULL */ + regArg = windowInitAccum(pParse, pMWin); + + sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr); + sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty); + VdbeCoverageNeverTaken(v); + + if( bReverse ){ + int addr2 = sqlite3VdbeCurrentAddr(v); + windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize); + sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty); + VdbeCoverageNeverTaken(v); + } + addrNext = sqlite3VdbeCurrentAddr(v); + + if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){ + int bCurrent = (pMWin->eStart==TK_CURRENT); + int addrJump = 0; /* Address of OP_Jump below */ + if( pMWin->eType==TK_RANGE ){ + int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0); + int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0); + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); + for(k=0; kiEphCsr); + sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); + + /* Jump to here to skip over flush_partition */ + sqlite3VdbeJumpHere(v, addrGoto); +} + + +/* +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** ... +** if( new partition ){ +** AggFinal (xFinalize) +** Gosub addrGosub +** ResetSorter eph-table +** } +** else if( new peer ){ +** AggFinal (xValue) +** Gosub addrGosub +** ResetSorter eph-table +** } +** AggStep +** Insert (record into eph-table) +** sqlite3WhereEnd() +** AggFinal (xFinalize) +** Gosub addrGosub +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING +** +** As above, except take no action for a "new peer". Invoke +** the sub-routine once only for each partition. +** +** RANGE BETWEEN CURRENT ROW AND CURRENT ROW +** +** As above, except that the "new peer" condition is handled in the +** same way as "new partition" (so there is no "else if" block). +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** As above, except assume every row is a "new peer". +*/ +static void windowCodeDefaultStep( + Parse *pParse, + Select *p, + WhereInfo *pWInfo, + int regGosub, + int addrGosub +){ + Window *pMWin = p->pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int k; + int iSubCsr = p->pSrc->a[0].iCursor; + int nSub = p->pSrc->a[0].pTab->nCol; + int reg = pParse->nMem+1; + int regRecord = reg+nSub; + int regRowid = regRecord+1; + int addr; + ExprList *pPart = pMWin->pPartition; + ExprList *pOrderBy = pMWin->pOrderBy; + + assert( pMWin->eType==TK_RANGE + || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) + ); + + assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy) + ); + + if( pMWin->eEnd==TK_UNBOUNDED ){ + pOrderBy = 0; + } + + pParse->nMem += nSub + 2; + + /* Load the individual column values of the row returned by + ** the sub-select into an array of registers. */ + for(k=0; knExpr : 0); + int addrGoto = 0; + int addrJump = 0; + int nPeer = (pOrderBy ? pOrderBy->nExpr : 0); + + if( pPart ){ + int regNewPart = reg + pMWin->nBufferCol; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2); + VdbeCoverageEqNe(v); + windowAggFinal(pParse, pMWin, 1); + if( pOrderBy ){ + addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); + } + } + + if( pOrderBy ){ + int regNewPeer = reg + pMWin->nBufferCol + nPart; + int regPeer = pMWin->regPart + nPart; + + if( addrJump ) sqlite3VdbeJumpHere(v, addrJump); + if( pMWin->eType==TK_RANGE ){ + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2); + VdbeCoverage(v); + }else{ + addrJump = 0; + } + windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT); + if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto); + } + + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1); + VdbeCoverage(v); + + sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); + sqlite3VdbeAddOp3( + v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1 + ); + + if( addrJump ) sqlite3VdbeJumpHere(v, addrJump); + } + + /* Invoke step function for window functions */ + windowAggStep(pParse, pMWin, -1, 0, reg, 0); + + /* Buffer the current row in the ephemeral table. */ + if( pMWin->nBufferCol>0 ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord); + }else{ + sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord); + sqlite3VdbeAppendP4(v, (void*)"", 0); + } + sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid); + + /* End the database scan loop. */ + sqlite3WhereEnd(pWInfo); + + windowAggFinal(pParse, pMWin, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1); + VdbeCoverage(v); +} + +/* +** Allocate and return a duplicate of the Window object indicated by the +** third argument. Set the Window.pOwner field of the new object to +** pOwner. +*/ +Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ + Window *pNew = 0; + if( ALWAYS(p) ){ + pNew = sqlite3DbMallocZero(db, sizeof(Window)); + if( pNew ){ + pNew->zName = sqlite3DbStrDup(db, p->zName); + pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); + pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); + pNew->eType = p->eType; + pNew->eEnd = p->eEnd; + pNew->eStart = p->eStart; + pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); + pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); + pNew->pOwner = pOwner; + } + } + return pNew; +} + +/* +** Return a copy of the linked list of Window objects passed as the +** second argument. +*/ +Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ + Window *pWin; + Window *pRet = 0; + Window **pp = &pRet; + + for(pWin=p; pWin; pWin=pWin->pNextWin){ + *pp = sqlite3WindowDup(db, 0, pWin); + if( *pp==0 ) break; + pp = &((*pp)->pNextWin); + } + + return pRet; +} + +/* +** sqlite3WhereBegin() has already been called for the SELECT statement +** passed as the second argument when this function is invoked. It generates +** code to populate the Window.regResult register for each window function and +** invoke the sub-routine at instruction addrGosub once for each row. +** This function calls sqlite3WhereEnd() before returning. +*/ +void sqlite3WindowCodeStep( + Parse *pParse, /* Parse context */ + Select *p, /* Rewritten SELECT statement */ + WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */ + int regGosub, /* Register for OP_Gosub */ + int addrGosub /* OP_Gosub here to return each row */ +){ + Window *pMWin = p->pWin; + + /* There are three different functions that may be used to do the work + ** of this one, depending on the window frame and the specific built-in + ** window functions used (if any). + ** + ** windowCodeRowExprStep() handles all "ROWS" window frames, except for: + ** + ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** + ** The exception is because windowCodeRowExprStep() implements all window + ** frame types by caching the entire partition in a temp table, and + ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to + ** implement without such a cache. + ** + ** windowCodeCacheStep() is used for: + ** + ** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ** + ** It is also used for anything not handled by windowCodeRowExprStep() + ** that invokes a built-in window function that requires the entire + ** partition to be cached in a temp table before any rows are returned + ** (e.g. nth_value() or percent_rank()). + ** + ** Finally, assuming there is no built-in window function that requires + ** the partition to be cached, windowCodeDefaultStep() is used for: + ** + ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW + ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** + ** windowCodeDefaultStep() is the only one of the three functions that + ** does not cache each partition in a temp table before beginning to + ** return rows. + */ + if( pMWin->eType==TK_ROWS + && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy) + ){ + VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()")); + windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub); + }else{ + Window *pWin; + int bCache = 0; /* True to use CacheStep() */ + + if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){ + bCache = 1; + }else{ + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pFunc; + if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE) + || (pFunc->zName==nth_valueName) + || (pFunc->zName==first_valueName) + || (pFunc->zName==leadName) + || (pFunc->zName==lagName) + ){ + bCache = 1; + break; + } + } + } + + /* Otherwise, call windowCodeDefaultStep(). */ + if( bCache ){ + VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()")); + windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub); + }else{ + VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()")); + windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub); + } + } +} + +#endif /* SQLITE_OMIT_WINDOWFUNC */ diff --git a/test/aggnested.test b/test/aggnested.test index a87c751eda..91de63b768 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -65,7 +65,7 @@ do_test aggnested-2.0 { t1.* FROM t1; } -} {A,B,B 3 33 333 3333} +} {A,B,B 1 11 111 1111} db2 close ##################### Test cases for ticket [bfbf38e5e9956ac69f] ############ diff --git a/test/all.test b/test/all.test index f6e722f2df..46e8115fba 100644 --- a/test/all.test +++ b/test/all.test @@ -16,6 +16,7 @@ source $testdir/permutations.test run_test_suite full +ifcapable rbu { run_test_suite rbu } run_test_suite no_optimization run_test_suite memsubsys1 run_test_suite memsubsys2 diff --git a/test/alter.test b/test/alter.test index 76c18cedc9..807a8f0171 100644 --- a/test/alter.test +++ b/test/alter.test @@ -681,21 +681,21 @@ do_test alter-8.2 { } {1 18 2 9} #-------------------------------------------------------------------------- -# alter-9.X - Special test: Make sure the sqlite_rename_trigger() and +# alter-9.X - Special test: Make sure the sqlite_rename_column() and # rename_table() functions do not crash when handed bad input. # -ifcapable trigger { - do_test alter-9.1 { - execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)} - } {{}} +do_test alter-9.1 { + execsql {SELECT SQLITE_RENAME_COLUMN(0,0,0,0,0,0,0,0,0)} +} {{}} +foreach {tn sql} { + 1 { SELECT SQLITE_RENAME_TABLE(0,0,0,0,0,0,0) } + 2 { SELECT SQLITE_RENAME_TABLE(10,20,30,40,50,60,70) } + 3 { SELECT SQLITE_RENAME_TABLE('foo','foo','foo','foo','foo','foo','foo') } +} { + do_test alter-9.2.$tn { + catch { execsql $sql } + } 1 } -do_test alter-9.2 { - execsql { - SELECT SQLITE_RENAME_TABLE(0,0); - SELECT SQLITE_RENAME_TABLE(10,20); - SELECT SQLITE_RENAME_TABLE('foo', 'foo'); - } -} {{} {} {}} #------------------------------------------------------------------------ # alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters @@ -875,51 +875,23 @@ do_execsql_test alter-16.2 { SELECT * FROM t16a_rn ORDER BY a; } {abc 1.25 99 xyzzy cba 5.5 98 fizzle} -#------------------------------------------------------------------------- -# Verify that NULL values into the internal-use-only sqlite_rename_*() -# functions do not cause problems. +# 2018-09-16 ticket b41031ea2b5372378cb3d2d43cf9fe2a4a5c2510 # -do_execsql_test alter-17.1 { - SELECT sqlite_rename_table('CREATE TABLE xyz(a,b,c)','abc'); -} {{CREATE TABLE "abc"(a,b,c)}} -do_execsql_test alter-17.2 { - SELECT sqlite_rename_table('CREATE TABLE xyz(a,b,c)',NULL); -} {{CREATE TABLE "(NULL)"(a,b,c)}} -do_execsql_test alter-17.3 { - SELECT sqlite_rename_table(NULL,'abc'); -} {{}} -do_execsql_test alter-17.4 { - SELECT sqlite_rename_trigger('CREATE TRIGGER r1 ON xyz WHEN','abc'); -} {{CREATE TRIGGER r1 ON "abc" WHEN}} -do_execsql_test alter-17.5 { - SELECT sqlite_rename_trigger('CREATE TRIGGER r1 ON xyz WHEN',NULL); -} {{CREATE TRIGGER r1 ON "(NULL)" WHEN}} -do_execsql_test alter-17.6 { - SELECT sqlite_rename_trigger(NULL,'abc'); -} {{}} -do_execsql_test alter-17.7 { - SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")', - 'xyzzy','lmnop'); -} {{CREATE TABLE t1(a REFERENCES "lmnop")}} -do_execsql_test alter-17.8 { - SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")', - 'xyzzy',NULL); -} {{CREATE TABLE t1(a REFERENCES "(NULL)")}} -do_execsql_test alter-17.9 { - SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")', - NULL, 'lmnop'); -} {{}} -do_execsql_test alter-17.10 { - SELECT sqlite_rename_parent(NULL,'abc','xyz'); -} {{}} -do_execsql_test alter-17.11 { - SELECT sqlite_rename_parent('create references ''','abc','xyz'); -} {{create references '}} -do_execsql_test alter-17.12 { - SELECT sqlite_rename_parent('create references "abc"123" ','abc','xyz'); -} {{create references "xyz"123" }} -do_execsql_test alter-17.13 { - SELECT sqlite_rename_parent("references '''",'abc','xyz'); -} {{references '''}} +ifcapable rtree { + db close + sqlite3 db :memory: + do_execsql_test alter-17.100 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE VIRTUAL TABLE t2 USING rtree(id,x0,x1); + INSERT INTO t1 VALUES(1,'apple'),(2,'fig'),(3,'pear'); + INSERT INTO t2 VALUES(1,1.0,2.0),(2,2.0,3.0),(3,1.5,3.5); + CREATE TRIGGER r1 AFTER UPDATE ON t1 BEGIN + DELETE FROM t2 WHERE id = OLD.a; + END; + ALTER TABLE t1 RENAME TO t3; + UPDATE t3 SET b='peach' WHERE a=2; + SELECT * FROM t2 ORDER BY 1; + } {1 1.0 2.0 3 1.5 3.5} +} finish_test diff --git a/test/alter4.test b/test/alter4.test index 5155110cf5..ca9175959b 100644 --- a/test/alter4.test +++ b/test/alter4.test @@ -394,4 +394,32 @@ do_test alter4-10.1 { } } {ok} +reset_db +do_execsql_test alter4-11.0 { + CREATE TABLE t1(c INTEGER PRIMARY KEY, d); + PRAGMA foreign_keys = on; + ALTER TABLE t1 ADD COLUMN e; +} + +do_execsql_test alter4-11.1 { + ALTER TABLE t1 ADD COLUMN f REFERENCES t1; +} + +do_catchsql_test alter4-11.2 { + ALTER TABLE t1 ADD COLUMN g REFERENCES t1 DEFAULT 4; +} {1 {Cannot add a REFERENCES column with non-NULL default value}} + +do_catchsql_test alter4-11.3 { + ALTER TABLE t2 ADD COLUMN g; +} {1 {no such table: t2}} + +ifcapable fts5 { + do_execsql_test alter4-11.4 { + CREATE VIRTUAL TABLE fff USING fts5(f); + } + do_catchsql_test alter4-11.2 { + ALTER TABLE fff ADD COLUMN g; + } {1 {virtual tables may not be altered}} +} + finish_test diff --git a/test/alterauth.test b/test/alterauth.test new file mode 100644 index 0000000000..12645b36f0 --- /dev/null +++ b/test/alterauth.test @@ -0,0 +1,72 @@ +# 2018 September 2 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] + +source $testdir/tester.tcl + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} +set testprefix alterauth + +set ::auth [list] +proc xAuth {type args} { + if {$type == "SQLITE_ALTER_TABLE"} { + lappend ::auth [concat $type [lrange $args 0 3]] + } + return SQLITE_OK +} +db auth xAuth + +do_execsql_test 1.0 { CREATE TABLE t1(a, b, c); } + +do_test 1.1 { + set ::auth [list] + execsql { ALTER TABLE t1 RENAME TO t2 } + set ::auth +} {{SQLITE_ALTER_TABLE main t1 {} {}}} + +do_test 1.2 { + set ::auth [list] + execsql { ALTER TABLE t2 RENAME c TO ccc } + set ::auth +} {{SQLITE_ALTER_TABLE main t2 {} {}}} + +do_test 1.3 { + set ::auth [list] + execsql { ALTER TABLE t2 ADD COLUMN d } + set ::auth +} {{SQLITE_ALTER_TABLE main t2 {} {}}} + +proc xAuth {type args} { + if {$type == "SQLITE_ALTER_TABLE"} { + return SQLITE_DENY + } + return SQLITE_OK +} + +do_test 2.1 { + catchsql { ALTER TABLE t2 RENAME TO t3 } +} {1 {not authorized}} + +do_test 2.2 { + catchsql { ALTER TABLE t2 RENAME d TO ddd } +} {1 {not authorized}} + +do_test 2.3 { + catchsql { ALTER TABLE t2 ADD COLUMN e } +} {1 {not authorized}} + +finish_test diff --git a/test/alterauth2.test b/test/alterauth2.test new file mode 100644 index 0000000000..bd589cda1d --- /dev/null +++ b/test/alterauth2.test @@ -0,0 +1,98 @@ +# 2018 October 6 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] + +source $testdir/tester.tcl + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} +set testprefix alterauth2 + +set ::auth [list] +proc xAuth {type args} { + lappend ::auth [concat $type [lrange $args 0 3]] + if {$type=="SQLITE_READ" && [lindex $args 0] == "t2"} breakpoint + return SQLITE_OK +} +db auth xAuth + +proc do_auth_test {tn sql authcode} { + set script " + set ::auth \[list\] + execsql {$sql} + lsort -unique \[set ::auth\] + " + + set normal [list {*}$authcode] + uplevel [list do_test $tn $script $normal] +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + CREATE VIEW v1 AS SELECT * FROM t1; + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + DELETE FROM t1 WHERE a0} + {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(d+d+d+d, c) WHERE d>0}} + + 13 {CREATE TABLE t1(a, b, c, FOREIGN KEY (b) REFERENCES t2)} + {CREATE TABLE t1(a, d, c, FOREIGN KEY (d) REFERENCES t2)} + + 14 {CREATE TABLE t1(a INTEGER, b TEXT, c BLOB, PRIMARY KEY(b))} + {CREATE TABLE t1(a INTEGER, d TEXT, c BLOB, PRIMARY KEY(d))} + + 15 {CREATE TABLE t1(a INTEGER, b INTEGER, c BLOB, PRIMARY KEY(b))} + {CREATE TABLE t1(a INTEGER, d INTEGER, c BLOB, PRIMARY KEY(d))} + + 16 {CREATE TABLE t1(a INTEGER, b INTEGER PRIMARY KEY, c BLOB)} + {CREATE TABLE t1(a INTEGER, d INTEGER PRIMARY KEY, c BLOB)} + + 17 {CREATE TABLE t1(a INTEGER, b INTEGER PRIMARY KEY, c BLOB, FOREIGN KEY (b) REFERENCES t2)} + {CREATE TABLE t1(a INTEGER, d INTEGER PRIMARY KEY, c BLOB, FOREIGN KEY (d) REFERENCES t2)} + +} { + reset_db + do_execsql_test 1.$tn.0 $before + + do_execsql_test 1.$tn.1 { + INSERT INTO t1 VALUES(1, 2, 3); + } + + do_execsql_test 1.$tn.2 { + ALTER TABLE t1 RENAME COLUMN b TO d; + } + + do_execsql_test 1.$tn.3 { + SELECT * FROM t1; + } {1 2 3} + + if {[string first INDEX $before]>0} { + set res $after + } else { + set res [list $after] + } + do_execsql_test 1.$tn.4 { + SELECT sql FROM sqlite_master WHERE tbl_name='t1' AND sql!='' + } $res +} + +#------------------------------------------------------------------------- +# +do_execsql_test 2.0 { + CREATE TABLE t3(a, b, c, d, e, f, g, h, i, j, k, l, m, FOREIGN KEY (b, c, d, e, f, g, h, i, j, k, l, m) REFERENCES t4); +} + +sqlite3 db2 test.db +do_execsql_test -db db2 2.1 { SELECT b FROM t3 } + +do_execsql_test 2.2 { + ALTER TABLE t3 RENAME b TO biglongname; + SELECT sql FROM sqlite_master WHERE name='t3'; +} {{CREATE TABLE t3(a, biglongname, c, d, e, f, g, h, i, j, k, l, m, FOREIGN KEY (biglongname, c, d, e, f, g, h, i, j, k, l, m) REFERENCES t4)}} + +do_execsql_test -db db2 2.3 { SELECT biglongname FROM t3 } + +#------------------------------------------------------------------------- +# +do_execsql_test 3.0 { + CREATE TABLE t4(x, y, z); + CREATE TRIGGER ttt AFTER INSERT ON t4 WHEN new.y<0 BEGIN + SELECT x, y, z FROM t4; + DELETE FROM t4 WHERE y=32; + UPDATE t4 SET x=y+1, y=0 WHERE y=32; + INSERT INTO t4(x, y, z) SELECT 4, 5, 6 WHERE 0; + END; + INSERT INTO t4 VALUES(3, 2, 1); +} + +do_execsql_test 3.1 { + ALTER TABLE t4 RENAME y TO abc; + SELECT sql FROM sqlite_master WHERE name='t4'; +} {{CREATE TABLE t4(x, abc, z)}} + +do_execsql_test 3.2 { + SELECT * FROM t4; +} {3 2 1} + +do_execsql_test 3.3 { INSERT INTO t4 VALUES(6, 5, 4); } {} + +do_execsql_test 3.4 { SELECT sql FROM sqlite_master WHERE type='trigger' } { +{CREATE TRIGGER ttt AFTER INSERT ON t4 WHEN new.abc<0 BEGIN + SELECT x, abc, z FROM t4; + DELETE FROM t4 WHERE abc=32; + UPDATE t4 SET x=abc+1, abc=0 WHERE abc=32; + INSERT INTO t4(x, abc, z) SELECT 4, 5, 6 WHERE 0; + END} +} + +#------------------------------------------------------------------------- +# +do_execsql_test 4.0 { + CREATE TABLE c1(a, b, FOREIGN KEY (a, b) REFERENCES p1(c, d)); + CREATE TABLE p1(c, d, PRIMARY KEY(c, d)); + PRAGMA foreign_keys = 1; + INSERT INTO p1 VALUES(1, 2); + INSERT INTO p1 VALUES(3, 4); +} + +do_execsql_test 4.1 { + ALTER TABLE p1 RENAME d TO "silly name"; + SELECT sql FROM sqlite_master WHERE name IN ('c1', 'p1'); +} { + {CREATE TABLE c1(a, b, FOREIGN KEY (a, b) REFERENCES p1(c, "silly name"))} + {CREATE TABLE p1(c, "silly name", PRIMARY KEY(c, "silly name"))} +} + +do_execsql_test 4.2 { INSERT INTO c1 VALUES(1, 2); } + +do_execsql_test 4.3 { + CREATE TABLE c2(a, b, FOREIGN KEY (a, b) REFERENCES p1); +} + +do_execsql_test 4.4 { + ALTER TABLE p1 RENAME "silly name" TO reasonable; + SELECT sql FROM sqlite_master WHERE name IN ('c1', 'c2', 'p1'); +} { + {CREATE TABLE c1(a, b, FOREIGN KEY (a, b) REFERENCES p1(c, "reasonable"))} + {CREATE TABLE p1(c, "reasonable", PRIMARY KEY(c, "reasonable"))} + {CREATE TABLE c2(a, b, FOREIGN KEY (a, b) REFERENCES p1)} +} + +#------------------------------------------------------------------------- + +do_execsql_test 5.0 { + CREATE TABLE t5(a, b, c); + CREATE INDEX t5a ON t5(a); + INSERT INTO t5 VALUES(1, 2, 3), (4, 5, 6); + ANALYZE; +} + +do_execsql_test 5.1 { + ALTER TABLE t5 RENAME b TO big; + SELECT big FROM t5; +} {2 5} + +do_catchsql_test 6.1 { + ALTER TABLE sqlite_stat1 RENAME tbl TO thetable; +} {1 {table sqlite_stat1 may not be altered}} + +#------------------------------------------------------------------------- +# +do_execsql_test 6.0 { + CREATE TABLE blob( + rid INTEGER PRIMARY KEY, + rcvid INTEGER, + size INTEGER, + uuid TEXT UNIQUE NOT NULL, + content BLOB, + CHECK( length(uuid)>=40 AND rid>0 ) + ); +} + +do_execsql_test 6.1 { + ALTER TABLE "blob" RENAME COLUMN "rid" TO "a1"; +} + +do_catchsql_test 6.2 { + ALTER TABLE "blob" RENAME COLUMN "a1" TO [where]; +} {0 {}} + +do_execsql_test 6.3 { + SELECT "where" FROM blob; +} {} + +#------------------------------------------------------------------------- +# Triggers. +# +db close +db2 close +reset_db +do_execsql_test 7.0 { + CREATE TABLE c(x); + INSERT INTO c VALUES(0); + CREATE TABLE t6("col a", "col b", "col c"); + CREATE TRIGGER zzz AFTER UPDATE OF "col a", "col c" ON t6 BEGIN + UPDATE c SET x=x+1; + END; +} + +do_execsql_test 7.1.1 { + INSERT INTO t6 VALUES(0, 0, 0); + UPDATE t6 SET "col c" = 1; + SELECT * FROM c; +} {1} + +do_execsql_test 7.1.2 { + ALTER TABLE t6 RENAME "col c" TO "col 3"; +} + +do_execsql_test 7.1.3 { + UPDATE t6 SET "col 3" = 0; + SELECT * FROM c; +} {2} + +#------------------------------------------------------------------------- +# Views. +# +reset_db +do_execsql_test 8.0 { + CREATE TABLE a1(x INTEGER, y TEXT, z BLOB, PRIMARY KEY(x)); + CREATE TABLE a2(a, b, c); + CREATE VIEW v1 AS SELECT x, y, z FROM a1; +} + +do_execsql_test 8.1 { + ALTER TABLE a1 RENAME y TO yyy; + SELECT sql FROM sqlite_master WHERE type='view'; +} {{CREATE VIEW v1 AS SELECT x, yyy, z FROM a1}} + +do_execsql_test 8.2.1 { + DROP VIEW v1; + CREATE VIEW v2 AS SELECT x, x+x, a, a+a FROM a1, a2; +} {} +do_execsql_test 8.2.2 { + ALTER TABLE a1 RENAME x TO xxx; +} +do_execsql_test 8.2.3 { + SELECT sql FROM sqlite_master WHERE type='view'; +} {{CREATE VIEW v2 AS SELECT xxx, xxx+xxx, a, a+a FROM a1, a2}} + +do_execsql_test 8.3.1 { + DROP TABLE a2; + DROP VIEW v2; + CREATE TABLE a2(a INTEGER PRIMARY KEY, b, c); + CREATE VIEW v2 AS SELECT xxx, xxx+xxx, a, a+a FROM a1, a2; +} {} +do_execsql_test 8.3.2 { + ALTER TABLE a1 RENAME xxx TO x; +} +do_execsql_test 8.3.3 { + SELECT sql FROM sqlite_master WHERE type='view'; +} {{CREATE VIEW v2 AS SELECT x, x+x, a, a+a FROM a1, a2}} + +do_execsql_test 8.4.0 { + CREATE TABLE b1(a, b, c); + CREATE TABLE b2(x, y, z); +} + +do_execsql_test 8.4.1 { + CREATE VIEW vvv AS SELECT c+c || coalesce(c, c) FROM b1, b2 WHERE x=c GROUP BY c HAVING c>0; + ALTER TABLE b1 RENAME c TO "a;b"; + SELECT sql FROM sqlite_master WHERE name='vvv'; +} {{CREATE VIEW vvv AS SELECT "a;b"+"a;b" || coalesce("a;b", "a;b") FROM b1, b2 WHERE x="a;b" GROUP BY "a;b" HAVING "a;b">0}} + +do_execsql_test 8.4.2 { + CREATE VIEW www AS SELECT b FROM b1 UNION ALL SELECT y FROM b2; + ALTER TABLE b1 RENAME b TO bbb; + SELECT sql FROM sqlite_master WHERE name='www'; +} {{CREATE VIEW www AS SELECT bbb FROM b1 UNION ALL SELECT y FROM b2}} + +db collate nocase {string compare} + +do_execsql_test 8.4.3 { + CREATE VIEW xxx AS SELECT a FROM b1 UNION SELECT x FROM b2 ORDER BY 1 COLLATE nocase; +} + +do_execsql_test 8.4.4 { + ALTER TABLE b2 RENAME x TO hello; + SELECT sql FROM sqlite_master WHERE name='xxx'; +} {{CREATE VIEW xxx AS SELECT a FROM b1 UNION SELECT hello FROM b2 ORDER BY 1 COLLATE nocase}} + +do_catchsql_test 8.4.5 { + CREATE VIEW zzz AS SELECT george, ringo FROM b1; + ALTER TABLE b1 RENAME a TO aaa; +} {1 {error in view zzz: no such column: george}} + +#------------------------------------------------------------------------- +# More triggers. +# +proc do_rename_column_test {tn old new lSchema} { + for {set i 0} {$i < 2} {incr i} { + drop_all_tables_and_views db + + set lSorted [list] + foreach sql $lSchema { + execsql $sql + lappend lSorted [string trim $sql] + } + set lSorted [lsort $lSorted] + + do_execsql_test $tn.$i.1 { + SELECT sql FROM sqlite_master WHERE sql!='' ORDER BY 1 + } $lSorted + + if {$i==1} { + db close + sqlite3 db test.db + } + + do_execsql_test $tn.$i.2 "ALTER TABLE t1 RENAME $old TO $new" + + do_execsql_test $tn.$i.3 { + SELECT sql FROM sqlite_master ORDER BY 1 + } [string map [list $old $new] $lSorted] + } +} + +foreach {tn old new lSchema} { + 1 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_) } + { CREATE TRIGGER AFTER INSERT ON t1 BEGIN + SELECT _x_ FROM t1; + END } + } + + 2 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_) } + { CREATE TABLE t2(c, d, e) } + { CREATE TRIGGER ttt AFTER INSERT ON t2 BEGIN + SELECT _x_ FROM t1; + END } + } + + 3 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_ INTEGER, PRIMARY KEY(_x_), CHECK(_x_>0)) } + { CREATE TABLE t2(c, d, e) } + { CREATE TRIGGER ttt AFTER UPDATE ON t1 BEGIN + INSERT INTO t2 VALUES(new.a, new.b, new._x_); + END } + } + + 4 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_ INTEGER, PRIMARY KEY(_x_), CHECK(_x_>0)) } + { CREATE TRIGGER ttt AFTER UPDATE ON t1 BEGIN + INSERT INTO t1 VALUES(new.a, new.b, new._x_) + ON CONFLICT (_x_) WHERE _x_>10 DO UPDATE SET _x_ = _x_+1; + END } + } + + 4 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_ INTEGER, PRIMARY KEY(_x_), CHECK(_x_>0)) } + { CREATE TRIGGER ttt AFTER UPDATE ON t1 BEGIN + INSERT INTO t1 VALUES(new.a, new.b, new._x_) + ON CONFLICT (_x_) WHERE _x_>10 DO NOTHING; + END } + } +} { + do_rename_column_test 9.$tn $old $new $lSchema +} + +#------------------------------------------------------------------------- +# Test that views can be edited even if there are missing collation +# sequences or user defined functions. +# +reset_db + +ifcapable vtab { + foreach {tn old new lSchema} { + 1 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_) } + { CREATE VIEW s1 AS SELECT a, b, _x_ FROM t1 WHERE _x_='abc' COLLATE xyz } + } + + 2 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_) } + { CREATE VIEW v1 AS SELECT a, b, _x_ FROM t1 WHERE scalar(_x_) } + } + + 3 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_) } + { CREATE VIEW v1 AS SELECT a, b, _x_ FROM t1 WHERE _x_ = unicode(1, 2, 3) } + } + + 4 _x_ _xxx_ { + { CREATE TABLE t1(a, b, _x_) } + { CREATE VIRTUAL TABLE e1 USING echo(t1) } + } + } { + register_echo_module db + do_rename_column_test 10.$tn $old $new $lSchema + } + + #-------------------------------------------------------------------------- + # Test that if a view or trigger refers to a virtual table for which the + # module is not available, RENAME COLUMN cannot proceed. + # + reset_db + register_echo_module db + do_execsql_test 11.0 { + CREATE TABLE x1(a, b, c); + CREATE VIRTUAL TABLE e1 USING echo(x1); + } + db close + sqlite3 db test.db + + do_execsql_test 11.1 { + ALTER TABLE x1 RENAME b TO bbb; + SELECT sql FROM sqlite_master; + } { {CREATE TABLE x1(a, bbb, c)} {CREATE VIRTUAL TABLE e1 USING echo(x1)} } + + do_execsql_test 11.2 { + CREATE VIEW v1 AS SELECT e1.*, x1.c FROM e1, x1; + } + + do_catchsql_test 11.3 { + ALTER TABLE x1 RENAME c TO ccc; + } {1 {error in view v1: no such module: echo}} +} + +#------------------------------------------------------------------------- +# Test some error conditions: +# +# 1. Renaming a column of a system table, +# 2. Renaming a column of a VIEW, +# 3. Renaming a column of a virtual table. +# 4. Renaming a column that does not exist. +# 5. Renaming a column of a table that does not exist. +# +reset_db +do_execsql_test 12.1.1 { + CREATE TABLE t1(a, b); + CREATE INDEX t1a ON t1(a); + INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 4); + ANALYZE; +} +do_catchsql_test 12.1.2 { + ALTER TABLE sqlite_stat1 RENAME idx TO theindex; +} {1 {table sqlite_stat1 may not be altered}} +do_execsql_test 12.1.3 { + SELECT sql FROM sqlite_master WHERE tbl_name = 'sqlite_stat1' +} {{CREATE TABLE sqlite_stat1(tbl,idx,stat)}} + +do_execsql_test 12.2.1 { + CREATE VIEW v1 AS SELECT * FROM t1; + CREATE VIEW v2(c, d) AS SELECT * FROM t1; +} +do_catchsql_test 12.2.2 { + ALTER TABLE v1 RENAME a TO z; +} {1 {cannot rename columns of view "v1"}} +do_catchsql_test 12.2.3 { + ALTER TABLE v2 RENAME c TO y; +} {1 {cannot rename columns of view "v2"}} + +ifcapable fts5 { + do_execsql_test 12.3.1 { + CREATE VIRTUAL TABLE ft USING fts5(a, b, c); + } + do_catchsql_test 12.3.2 { + ALTER TABLE ft RENAME a TO z; + } {1 {cannot rename columns of virtual table "ft"}} +} + +do_execsql_test 12.4.1 { + CREATE TABLE t2(x, y, z); +} +do_catchsql_test 12.4.2 { + ALTER TABLE t2 RENAME COLUMN a TO b; +} {1 {no such column: "a"}} + +do_catchsql_test 12.5.1 { + ALTER TABLE t3 RENAME COLUMN a TO b; +} {1 {no such table: t3}} + +#------------------------------------------------------------------------- +# Test the effect of some parse/resolve errors. +# +reset_db +do_execsql_test 13.1.1 { + CREATE TABLE x1(i INTEGER, t TEXT UNIQUE); + CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN + SELECT * FROM nosuchtable; + END; +} + +do_catchsql_test 13.1.2 { + ALTER TABLE x1 RENAME COLUMN t TO ttt; +} {1 {error in trigger tr1: no such table: main.nosuchtable}} + +do_execsql_test 13.1.3 { + DROP TRIGGER tr1; + CREATE INDEX x1i ON x1(i); + SELECT sql FROM sqlite_master WHERE name='x1i'; +} {{CREATE INDEX x1i ON x1(i)}} + +do_execsql_test 13.1.4 { + PRAGMA writable_schema = 1; + UPDATE sqlite_master SET sql = 'CREATE INDEX x1i ON x1(j)' WHERE name='x1i'; +} {} + +do_catchsql_test 13.1.5 { + ALTER TABLE x1 RENAME COLUMN t TO ttt; +} {1 {error in index x1i: no such column: j}} + +do_execsql_test 13.1.6 { + UPDATE sqlite_master SET sql = '' WHERE name='x1i'; +} {} + +do_catchsql_test 13.1.7 { + ALTER TABLE x1 RENAME COLUMN t TO ttt; +} {1 {database disk image is malformed}} + +do_execsql_test 13.1.8 { + DELETE FROM sqlite_master WHERE name = 'x1i'; +} + +do_execsql_test 13.2.0 { + CREATE TABLE data(x UNIQUE, y, z); +} +foreach {tn trigger error} { + 1 { + CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN + UPDATE data SET x=x+1 WHERE zzz=new.i; + END; + } {no such column: zzz} + + 2 { + CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN + INSERT INTO data(x, y) VALUES(new.i, new.t, 1) + ON CONFLICT (x) DO UPDATE SET z=zz+1; + END; + } {no such column: zz} + + 3 { + CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN + INSERT INTO x1(i, t) VALUES(new.i+1, new.t||'1') + ON CONFLICT (tttttt) DO UPDATE SET t=i+1; + END; + } {no such column: tttttt} + + 4 { + CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN + INSERT INTO nosuchtable VALUES(new.i, new.t); + END; + } {no such table: main.nosuchtable} +} { + do_execsql_test 13.2.$tn.1 " + DROP TRIGGER IF EXISTS tr1; + $trigger + " + + do_catchsql_test 13.2.$tn.2 { + ALTER TABLE x1 RENAME COLUMN t TO ttt; + } "1 {error in trigger tr1: $error}" +} + +#------------------------------------------------------------------------- +# Passing invalid parameters directly to sqlite_rename_column(). +# +do_execsql_test 14.1 { + CREATE TABLE ddd(sql, type, object, db, tbl, icol, znew, bquote); + INSERT INTO ddd VALUES( + 'CREATE TABLE x1(i INTEGER, t TEXT)', + 'table', 'x1', 'main', 'x1', -1, 'zzz', 0 + ), ( + 'CREATE TABLE x1(i INTEGER, t TEXT)', + 'table', 'x1', 'main', 'x1', 2, 'zzz', 0 + ), ( + 'CREATE TABLE x1(i INTEGER, t TEXT)', + 'table', 'x1', 'main', 'notable', 0, 'zzz', 0 + ), ( + 'CREATE TABLE x1(i INTEGER, t TEXT)', + 'table', 'x1', 'main', 'ddd', -1, 'zzz', 0 + ); +} {} + +do_execsql_test 14.2 { + SELECT + sqlite_rename_column(sql, type, object, db, tbl, icol, znew, bquote, 0) + FROM ddd; +} {{} {} {} {}} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 15.0 { + CREATE TABLE xxx(a, b, c); + SELECT a AS d FROM xxx WHERE d=0; +} + +do_execsql_test 15.1 { + CREATE VIEW vvv AS SELECT a AS d FROM xxx WHERE d=0; + ALTER TABLE xxx RENAME a TO xyz; +} + +do_execsql_test 15.2 { + SELECT sql FROM sqlite_master WHERE type='view'; +} {{CREATE VIEW vvv AS SELECT xyz AS d FROM xxx WHERE d=0}} + +#------------------------------------------------------------------------- +# +do_execsql_test 16.1.0 { + CREATE TABLE t1(a,b,c); + CREATE TABLE t2(d,e,f); + INSERT INTO t1 VALUES(1,2,3); + INSERT INTO t2 VALUES(4,5,6); + CREATE VIEW v4 AS SELECT a, d FROM t1, t2; + SELECT * FROM v4; +} {1 4} + +do_catchsql_test 16.1.1 { + ALTER TABLE t2 RENAME d TO a; +} {1 {error in view v4 after rename: ambiguous column name: a}} + +do_execsql_test 16.1.2 { + SELECT * FROM v4; +} {1 4} + +do_execsql_test 16.1.3 { + CREATE UNIQUE INDEX t2d ON t2(d); + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO t2 VALUES(new.a, new.b, new.c) + ON CONFLICT(d) DO UPDATE SET f = excluded.f; + END; +} + +do_execsql_test 16.1.4 { + INSERT INTO t1 VALUES(4, 8, 456); + SELECT * FROM t2; +} {4 5 456} + +do_execsql_test 16.1.5 { + ALTER TABLE t2 RENAME COLUMN f TO "big f"; + INSERT INTO t1 VALUES(4, 0, 20456); + SELECT * FROM t2; +} {4 5 20456} + +do_execsql_test 16.1.6 { + ALTER TABLE t1 RENAME COLUMN c TO "big c"; + INSERT INTO t1 VALUES(4, 0, 0); + SELECT * FROM t2; +} {4 5 0} + +do_execsql_test 16.2.1 { + CREATE VIEW temp.v5 AS SELECT "big c" FROM t1; + SELECT * FROM v5; +} {3 456 20456 0} + +do_execsql_test 16.2.2 { + ALTER TABLE t1 RENAME COLUMN "big c" TO reallybigc; +} {} + +do_execsql_test 16.2.3 { + SELECT * FROM v5; +} {3 456 20456 0} + +#------------------------------------------------------------------------- +# +do_execsql_test 17.0 { + CREATE TABLE u7(x, y, z); + CREATE TRIGGER u7t AFTER INSERT ON u7 BEGIN + INSERT INTO u8 VALUES(new.x, new.y, new.z); + END; +} {} +do_catchsql_test 17.1 { + ALTER TABLE u7 RENAME x TO xxx; +} {1 {error in trigger u7t: no such table: main.u8}} + +do_execsql_test 17.2 { + CREATE TEMP TABLE uu7(x, y, z); + CREATE TRIGGER uu7t AFTER INSERT ON uu7 BEGIN + INSERT INTO u8 VALUES(new.x, new.y, new.z); + END; +} {} +do_catchsql_test 17.3 { + ALTER TABLE uu7 RENAME x TO xxx; +} {1 {error in trigger uu7t: no such table: u8}} + +reset_db +forcedelete test.db2 +do_execsql_test 18.0 { + ATTACH 'test.db2' AS aux; + CREATE TABLE t1(a); + CREATE TABLE aux.log(v); + CREATE TEMP TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO log VALUES(new.a); + END; + INSERT INTO t1 VALUES(111); + SELECT v FROM log; +} {111} + +do_execsql_test 18.1 { + ALTER TABLE t1 RENAME a TO b; +} + +reset_db +do_execsql_test 19.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(c, d); + CREATE VIEW v2(e) AS SELECT coalesce(t2.c,t1.a) FROM t1, t2 WHERE t1.b=t2.d; +} + +do_execsql_test 19.1 { + ALTER TABLE t1 RENAME a TO f; + SELECT sql FROM sqlite_master WHERE name = 'v2'; +} { + {CREATE VIEW v2(e) AS SELECT coalesce(t2.c,t1.f) FROM t1, t2 WHERE t1.b=t2.d} +} + + + +finish_test diff --git a/test/alterlegacy.test b/test/alterlegacy.test new file mode 100644 index 0000000000..9f7777670d --- /dev/null +++ b/test/alterlegacy.test @@ -0,0 +1,470 @@ +# 2018 September 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix alterlegacy + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} + +do_execsql_test 1.0 { + PRAGMA legacy_alter_table = 1; + CREATE TABLE t1(a, b, CHECK(t1.a != t1.b)); + CREATE TABLE t2(a, b); + CREATE INDEX t2expr ON t2(a) WHERE t2.b>0; +} + +do_execsql_test 1.1 { + SELECT sql FROM sqlite_master +} { + {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))} + {CREATE TABLE t2(a, b)} + {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0} +} + +# Legacy behavior is to corrupt the schema in this case, as the table name in +# the CHECK constraint is incorrect after "t1" is renamed. This version is +# slightly different - it rejects the change and rolls back the transaction. +do_catchsql_test 1.2 { + ALTER TABLE t1 RENAME TO t1new; +} {1 {no such column: t1.a}} + +do_execsql_test 1.3 { + CREATE TABLE t3(c, d); + ALTER TABLE t3 RENAME TO t3new; + DROP TABLE t3new; +} + +do_execsql_test 1.4 { + SELECT sql FROM sqlite_master +} { + {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))} + {CREATE TABLE t2(a, b)} + {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0} +} + + +do_catchsql_test 1.3 { + ALTER TABLE t2 RENAME TO t2new; +} {1 {no such column: t2.b}} +do_execsql_test 1.4 { + SELECT sql FROM sqlite_master +} { + {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))} + {CREATE TABLE t2(a, b)} + {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0} +} + + +#------------------------------------------------------------------------- +reset_db +ifcapable vtab { + register_echo_module db + + do_execsql_test 2.0 { + PRAGMA legacy_alter_table = 1; + CREATE TABLE abc(a, b, c); + INSERT INTO abc VALUES(1, 2, 3); + CREATE VIRTUAL TABLE eee USING echo('abc'); + SELECT * FROM eee; + } {1 2 3} + + do_execsql_test 2.1 { + ALTER TABLE eee RENAME TO fff; + SELECT * FROM fff; + } {1 2 3} + + db close + sqlite3 db test.db + + do_catchsql_test 2.2 { + ALTER TABLE fff RENAME TO ggg; + } {1 {no such module: echo}} +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + PRAGMA legacy_alter_table = 1; + CREATE TABLE txx(a, b, c); + INSERT INTO txx VALUES(1, 2, 3); + CREATE VIEW vvv AS SELECT main.txx.a, txx.b, c FROM txx; + CREATE VIEW uuu AS SELECT main.one.a, one.b, c FROM txx AS one; + CREATE VIEW temp.ttt AS SELECT main.txx.a, txx.b, one.b, main.one.a FROM txx AS one, txx; +} + +do_execsql_test 3.1.1 { + SELECT * FROM vvv; +} {1 2 3} +do_execsql_test 3.1.2a { + ALTER TABLE txx RENAME TO "t xx"; +} +do_catchsql_test 3.1.2b { + SELECT * FROM vvv; +} {1 {no such table: main.txx}} +do_execsql_test 3.1.3 { + SELECT sql FROM sqlite_master WHERE name='vvv'; +} {{CREATE VIEW vvv AS SELECT main.txx.a, txx.b, c FROM txx}} + + +do_catchsql_test 3.2.1 { + SELECT * FROM uuu; +} {1 {no such table: main.txx}} +do_execsql_test 3.2.2 { + SELECT sql FROM sqlite_master WHERE name='uuu';; +} {{CREATE VIEW uuu AS SELECT main.one.a, one.b, c FROM txx AS one}} + +do_catchsql_test 3.3.1 { + SELECT * FROM ttt; +} {1 {no such table: txx}} +do_execsql_test 3.3.2 { + SELECT sql FROM sqlite_temp_master WHERE name='ttt'; +} {{CREATE VIEW ttt AS SELECT main.txx.a, txx.b, one.b, main.one.a FROM txx AS one, txx}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + PRAGMA legacy_alter_table = 1; + CREATE table t1(x, y); + CREATE table t2(a, b); + + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + SELECT t1.x, * FROM t1, t2; + INSERT INTO t2 VALUES(new.x, new.y); + END; +} + +do_execsql_test 4.1 { + INSERT INTO t1 VALUES(1, 1); + ALTER TABLE t1 RENAME TO t11; +} +do_catchsql_test 4.1a { + INSERT INTO t11 VALUES(2, 2); +} {1 {no such table: main.t1}} +do_execsql_test 4.1b { + ALTER TABLE t11 RENAME TO t1; + ALTER TABLE t2 RENAME TO t22; +} +do_catchsql_test 4.1c { + INSERT INTO t1 VALUES(3, 3); +} {1 {no such table: main.t2}} + +proc squish {a} { + string trim [regsub -all {[[:space:]][[:space:]]*} $a { }] +} +db func squish squish +do_test 4.2 { + execsql { SELECT squish(sql) FROM sqlite_master WHERE name = 'tr1' } +} [list [squish { + CREATE TRIGGER tr1 AFTER INSERT ON "t1" BEGIN + SELECT t1.x, * FROM t1, t2; + INSERT INTO t2 VALUES(new.x, new.y); + END +}]] + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + PRAGMA legacy_alter_table = 1; + CREATE TABLE t9(a, b, c); + CREATE TABLE t10(a, b, c); + CREATE TEMP TABLE t9(a, b, c); + + CREATE TRIGGER temp.t9t AFTER INSERT ON temp.t9 BEGIN + INSERT INTO t10 VALUES(new.a, new.b, new.c); + END; + + INSERT INTO temp.t9 VALUES(1, 2, 3); + SELECT * FROM t10; +} {1 2 3} + +do_execsql_test 5.1 { + ALTER TABLE temp.t9 RENAME TO 't1234567890' +} + +do_execsql_test 5.2 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t2 VALUES(3, 4); + CREATE VIEW v AS SELECT one.a, one.b, t2.a, t2.b FROM t1 AS one, t2; + SELECT * FROM v; +} {1 2 3 4} + +do_execsql_test 5.3 { + ALTER TABLE t2 RENAME TO one; +} {} + +do_catchsql_test 5.4 { + SELECT * FROM v +} {1 {no such table: main.t2}} + +do_execsql_test 5.5 { + ALTER TABLE one RENAME TO t2; + DROP VIEW v; + CREATE VIEW temp.vv AS SELECT one.a, one.b, t2.a, t2.b FROM t1 AS one, t2; + SELECT * FROM vv; +} {1 2 3 4} + +do_execsql_test 5.6 { + ALTER TABLE t2 RENAME TO one; +} {} +do_catchsql_test 5.7 { + SELECT * FROM vv +} {1 {no such table: t2}} + +#------------------------------------------------------------------------- + +ifcapable vtab { + register_tcl_module db + proc tcl_command {method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c)" + } + } + return {} + } + + do_execsql_test 6.0 { + CREATE VIRTUAL TABLE x1 USING tcl(tcl_command); + } + + do_execsql_test 6.1 { + ALTER TABLE x1 RENAME TO x2; + SELECT sql FROM sqlite_master WHERE name = 'x2' + } {{CREATE VIRTUAL TABLE "x2" USING tcl(tcl_command)}} + + do_execsql_test 7.1 { + CREATE TABLE ddd(db, sql, zOld, zNew, bTemp); + INSERT INTO ddd VALUES( + 'main', 'CREATE TABLE x1(i INTEGER, t TEXT)', 'ddd', NULL, 0 + ), ( + 'main', 'CREATE TABLE x1(i INTEGER, t TEXT)', NULL, 'eee', 0 + ), ( + 'main', NULL, 'ddd', 'eee', 0 + ); + } {} +} + +#------------------------------------------------------------------------- +# +reset_db +forcedelete test.db2 +do_execsql_test 8.1 { + PRAGMA legacy_alter_table = 1; + ATTACH 'test.db2' AS aux; + PRAGMA foreign_keys = on; + CREATE TABLE aux.p1(a INTEGER PRIMARY KEY, b); + CREATE TABLE aux.c1(x INTEGER PRIMARY KEY, y REFERENCES p1(a)); + INSERT INTO aux.p1 VALUES(1, 1); + INSERT INTO aux.p1 VALUES(2, 2); + INSERT INTO aux.c1 VALUES(NULL, 2); + CREATE TABLE aux.c2(x INTEGER PRIMARY KEY, y REFERENCES c1(a)); +} + +do_execsql_test 8.2 { + ALTER TABLE aux.p1 RENAME TO ppp; +} + +do_execsql_test 8.2 { + INSERT INTO aux.c1 VALUES(NULL, 1); + SELECT sql FROM aux.sqlite_master WHERE name = 'c1'; +} {{CREATE TABLE c1(x INTEGER PRIMARY KEY, y REFERENCES "ppp"(a))}} + +reset_db +do_execsql_test 9.0 { + PRAGMA legacy_alter_table = 1; + CREATE TABLE t1(a, b, c); + CREATE VIEW v1 AS SELECT * FROM t2; +} +do_execsql_test 9.1 { + ALTER TABLE t1 RENAME TO t3; +} {} +do_execsql_test 9.1b { + ALTER TABLE t3 RENAME TO t1; +} {} +do_execsql_test 9.2 { + DROP VIEW v1; + CREATE TRIGGER tr AFTER INSERT ON t1 BEGIN + INSERT INTO t2 VALUES(new.a); + END; +} +do_execsql_test 9.3 { + ALTER TABLE t1 RENAME TO t3; +} {} + +forcedelete test.db2 +do_execsql_test 9.4 { + ALTER TABLE t3 RENAME TO t1; + DROP TRIGGER tr; + + ATTACH 'test.db2' AS aux; + CREATE TRIGGER tr AFTER INSERT ON t1 WHEN new.a IS NULL BEGIN SELECT 1, 2, 3; END; + + CREATE TABLE aux.t1(x); + CREATE TEMP TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END; +} +do_execsql_test 9.5 { + ALTER TABLE main.t1 RENAME TO t3; +} +do_execsql_test 9.6 { + SELECT sql FROM sqlite_temp_master; + SELECT sql FROM sqlite_master WHERE type='trigger'; +} { + {CREATE TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END} + {CREATE TRIGGER tr AFTER INSERT ON "t3" WHEN new.a IS NULL BEGIN SELECT 1, 2, 3; END} +} + +#------------------------------------------------------------------------- +reset_db +ifcapable fts5 { + do_execsql_test 10.0 { + PRAGMA legacy_alter_table = 1; + CREATE VIRTUAL TABLE fff USING fts5(x, y, z); + } + + do_execsql_test 10.1 { + BEGIN; + INSERT INTO fff VALUES('a', 'b', 'c'); + ALTER TABLE fff RENAME TO ggg; + COMMIT; + } + + do_execsql_test 10.2 { + SELECT * FROM ggg; + } {a b c} +} + +#------------------------------------------------------------------------- +reset_db +forcedelete test.db2 +db func trigger trigger +set ::trigger [list] +proc trigger {args} { + lappend ::trigger $args +} +do_execsql_test 11.0 { + PRAGMA legacy_alter_table = 1; + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.t1(a, b, c); + CREATE TABLE main.t1(a, b, c); + CREATE TEMP TRIGGER tr AFTER INSERT ON aux.t1 BEGIN + SELECT trigger(new.a, new.b, new.c); + END; +} + +do_execsql_test 11.1 { + INSERT INTO main.t1 VALUES(1, 2, 3); + INSERT INTO aux.t1 VALUES(4, 5, 6); +} +do_test 11.2 { set ::trigger } {{4 5 6}} + +do_execsql_test 11.3 { + SELECT name, tbl_name FROM sqlite_temp_master; +} {tr t1} + +do_execsql_test 11.4 { + ALTER TABLE main.t1 RENAME TO t2; + SELECT name, tbl_name FROM sqlite_temp_master; +} {tr t1} + +do_execsql_test 11.5 { + ALTER TABLE aux.t1 RENAME TO t2; + SELECT name, tbl_name FROM sqlite_temp_master; +} {tr t2} + +do_execsql_test 11.6 { + INSERT INTO aux.t2 VALUES(7, 8, 9); +} +do_test 11.7 { set ::trigger } {{4 5 6} {7 8 9}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 12.0 { + PRAGMA legacy_alter_table = 1; + CREATE TABLE t1(a); + CREATE TABLE t2(w); + CREATE TRIGGER temp.r1 AFTER INSERT ON main.t2 BEGIN + INSERT INTO t1(a) VALUES(new.w); + END; + CREATE TEMP TABLE t2(x); +} + +do_execsql_test 12.1 { + ALTER TABLE main.t2 RENAME TO t3; +} + +do_execsql_test 12.2 { + INSERT INTO t3 VALUES('WWW'); + SELECT * FROM t1; +} {WWW} + + +#------------------------------------------------------------------------- +reset_db + +ifcapable rtree { + do_execsql_test 14.0 { + PRAGMA legacy_alter_table = 1; + CREATE VIRTUAL TABLE rt USING rtree(id, minx, maxx, miny, maxy); + + CREATE TABLE "mytable" ( "fid" INTEGER PRIMARY KEY, "geom" BLOB); + + CREATE TRIGGER tr1 AFTER UPDATE OF "geom" ON "mytable" + WHEN OLD."fid" = NEW."fid" AND NEW."geom" IS NULL BEGIN + DELETE FROM rt WHERE id = OLD."fid"; + END; + + INSERT INTO mytable VALUES(1, X'abcd'); + } + + do_execsql_test 14.1 { + UPDATE mytable SET geom = X'1234' + } + + do_execsql_test 14.2 { + ALTER TABLE mytable RENAME TO mytable_renamed; + } + + do_execsql_test 14.3 { + CREATE TRIGGER tr2 AFTER INSERT ON mytable_renamed BEGIN + DELETE FROM rt WHERE id=(SELECT min(id) FROM rt); + END; + } + + do_execsql_test 14.4 { + ALTER TABLE mytable_renamed RENAME TO mytable2; + } +} + +reset_db +do_execsql_test 14.5 { + PRAGMA legacy_alter_table = 1; + CREATE TABLE t1(a, b, c); + CREATE VIEW v1 AS SELECT * FROM t1; + CREATE TRIGGER xyz AFTER INSERT ON t1 BEGIN + SELECT a, b FROM v1; + END; +} +do_execsql_test 14.6 { + ALTER TABLE t1 RENAME TO tt1; +} + + +finish_test + diff --git a/test/altermalloc.test b/test/altermalloc.test index a35e7d5a34..22ea158463 100644 --- a/test/altermalloc.test +++ b/test/altermalloc.test @@ -19,7 +19,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl # If SQLITE_OMIT_ALTERTABLE is defined, omit this file. -ifcapable !altertable||!memdebug { +ifcapable !altertable { finish_test return } diff --git a/test/altermalloc2.test b/test/altermalloc2.test new file mode 100644 index 0000000000..610b3f6bf0 --- /dev/null +++ b/test/altermalloc2.test @@ -0,0 +1,101 @@ +# 2018 August 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set testprefix altermalloc2 + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(abcd, efgh); +} +faultsim_save_and_close + +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen +} -body { + execsql { + ALTER TABLE t1 RENAME abcd TO dcba + } +} -test { + faultsim_test_result {0 {}} +} + +catch {db close} +forcedelete test.db +sqlite3 db test.db +do_execsql_test 2.0 { + PRAGMA encoding = 'utf-16'; + CREATE TABLE t1(abcd, efgh); +} +faultsim_save_and_close + +do_faultsim_test 2 -prep { + faultsim_restore_and_reopen +} -body { + execsql { + ALTER TABLE t1 RENAME abcd TO dcba + } +} -test { + faultsim_test_result {0 {}} +} + + +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(abcd, efgh); + CREATE VIEW v1 AS SELECT * FROM t1 WHERE abcd>efgh; +} +faultsim_save_and_close + +do_faultsim_test 3 -prep { + faultsim_restore_and_reopen +} -body { + execsql { + ALTER TABLE t1 RENAME abcd TO dcba + } +} -test { + faultsim_test_result {0 {}} +} + +reset_db +do_execsql_test 4.0 { + CREATE TABLE rr(a, b); + CREATE VIEW vv AS SELECT * FROM rr; + + CREATE TRIGGER vv1 INSTEAD OF INSERT ON vv BEGIN + SELECT 1, 2, 3; + END; + CREATE TRIGGER tr1 AFTER INSERT ON rr BEGIN + INSERT INTO vv VALUES(new.a, new.b); + END; +} {} + +faultsim_save_and_close +do_faultsim_test 4 -faults oom-* -prep { + faultsim_restore_and_reopen + execsql { SELECT * FROM sqlite_master } +} -body { + execsql { + ALTER TABLE rr RENAME a TO c; + } +} -test { + faultsim_test_result {0 {}} +} + +finish_test diff --git a/test/altertab.test b/test/altertab.test new file mode 100644 index 0000000000..819aa67201 --- /dev/null +++ b/test/altertab.test @@ -0,0 +1,508 @@ +# 2018 August 24 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix altertab + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, CHECK(t1.a != t1.b)); + + CREATE TABLE t2(a, b); + CREATE INDEX t2expr ON t2(a) WHERE t2.b>0; +} + +do_execsql_test 1.1 { + SELECT sql FROM sqlite_master +} { + {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))} + {CREATE TABLE t2(a, b)} + {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0} +} + +do_execsql_test 1.2 { + ALTER TABLE t1 RENAME TO t1new; +} + +do_execsql_test 1.3 { + CREATE TABLE t3(c, d); + ALTER TABLE t3 RENAME TO t3new; + DROP TABLE t3new; +} + +do_execsql_test 1.4 { + SELECT sql FROM sqlite_master +} { + {CREATE TABLE "t1new"(a, b, CHECK("t1new".a != "t1new".b))} + {CREATE TABLE t2(a, b)} + {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0} +} + + +do_execsql_test 1.3 { + ALTER TABLE t2 RENAME TO t2new; +} +do_execsql_test 1.4 { + SELECT sql FROM sqlite_master +} { + {CREATE TABLE "t1new"(a, b, CHECK("t1new".a != "t1new".b))} + {CREATE TABLE "t2new"(a, b)} + {CREATE INDEX t2expr ON "t2new"(a) WHERE "t2new".b>0} +} + + +#------------------------------------------------------------------------- +reset_db +ifcapable vtab { + register_echo_module db + + do_execsql_test 2.0 { + CREATE TABLE abc(a, b, c); + INSERT INTO abc VALUES(1, 2, 3); + CREATE VIRTUAL TABLE eee USING echo('abc'); + SELECT * FROM eee; + } {1 2 3} + + do_execsql_test 2.1 { + ALTER TABLE eee RENAME TO fff; + SELECT * FROM fff; + } {1 2 3} + + db close + sqlite3 db test.db + + do_catchsql_test 2.2 { + ALTER TABLE fff RENAME TO ggg; + } {1 {no such module: echo}} +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE TABLE txx(a, b, c); + INSERT INTO txx VALUES(1, 2, 3); + CREATE VIEW vvv AS SELECT main.txx.a, txx.b, c FROM txx; + CREATE VIEW uuu AS SELECT main.one.a, one.b, c FROM txx AS one; + CREATE VIEW temp.ttt AS SELECT main.txx.a, txx.b, one.b, main.one.a FROM txx AS one, txx; +} + +do_execsql_test 3.1.1 { + SELECT * FROM vvv; +} {1 2 3} +do_execsql_test 3.1.2 { + ALTER TABLE txx RENAME TO "t xx"; + SELECT * FROM vvv; +} {1 2 3} +do_execsql_test 3.1.3 { + SELECT sql FROM sqlite_master WHERE name='vvv'; +} {{CREATE VIEW vvv AS SELECT main."t xx".a, "t xx".b, c FROM "t xx"}} + + +do_execsql_test 3.2.1 { + SELECT * FROM uuu; +} {1 2 3} +do_execsql_test 3.2.2 { + SELECT sql FROM sqlite_master WHERE name='uuu';; +} {{CREATE VIEW uuu AS SELECT main.one.a, one.b, c FROM "t xx" AS one}} + +do_execsql_test 3.3.1 { + SELECT * FROM ttt; +} {1 2 2 1} +do_execsql_test 3.3.2 { + SELECT sql FROM sqlite_temp_master WHERE name='ttt'; +} {{CREATE VIEW ttt AS SELECT main."t xx".a, "t xx".b, one.b, main.one.a FROM "t xx" AS one, "t xx"}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE table t1(x, y); + CREATE table t2(a, b); + + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + SELECT t1.x, * FROM t1, t2; + INSERT INTO t2 VALUES(new.x, new.y); + END; +} + +do_execsql_test 4.1 { + INSERT INTO t1 VALUES(1, 1); + ALTER TABLE t1 RENAME TO t11; + INSERT INTO t11 VALUES(2, 2); + ALTER TABLE t2 RENAME TO t22; + INSERT INTO t11 VALUES(3, 3); +} + +proc squish {a} { + string trim [regsub -all {[[:space:]][[:space:]]*} $a { }] +} +db func squish squish +do_test 4.2 { + execsql { SELECT squish(sql) FROM sqlite_master WHERE name = 'tr1' } +} [list [squish { + CREATE TRIGGER tr1 AFTER INSERT ON "t11" BEGIN + SELECT "t11".x, * FROM "t11", "t22"; + INSERT INTO "t22" VALUES(new.x, new.y); + END +}]] + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE TABLE t9(a, b, c); + CREATE TABLE t10(a, b, c); + CREATE TEMP TABLE t9(a, b, c); + + CREATE TRIGGER temp.t9t AFTER INSERT ON temp.t9 BEGIN + INSERT INTO t10 VALUES(new.a, new.b, new.c); + END; + + INSERT INTO temp.t9 VALUES(1, 2, 3); + SELECT * FROM t10; +} {1 2 3} + +do_execsql_test 5.1 { + ALTER TABLE temp.t9 RENAME TO 't1234567890' +} + +do_execsql_test 5.2 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t2 VALUES(3, 4); + CREATE VIEW v AS SELECT one.a, one.b, t2.a, t2.b FROM t1 AS one, t2; + SELECT * FROM v; +} {1 2 3 4} + +do_catchsql_test 5.3 { + ALTER TABLE t2 RENAME TO one; +} {1 {error in view v after rename: ambiguous column name: one.a}} + +do_execsql_test 5.4 { + SELECT * FROM v +} {1 2 3 4} + +do_execsql_test 5.5 { + DROP VIEW v; + CREATE VIEW temp.vv AS SELECT one.a, one.b, t2.a, t2.b FROM t1 AS one, t2; + SELECT * FROM vv; +} {1 2 3 4} + +do_catchsql_test 5.6 { + ALTER TABLE t2 RENAME TO one; +} {1 {error in view vv after rename: ambiguous column name: one.a}} + +#------------------------------------------------------------------------- + +ifcapable vtab { + register_tcl_module db + proc tcl_command {method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c)" + } + } + return {} + } + + do_execsql_test 6.0 { + CREATE VIRTUAL TABLE x1 USING tcl(tcl_command); + } + + do_execsql_test 6.1 { + ALTER TABLE x1 RENAME TO x2; + SELECT sql FROM sqlite_master WHERE name = 'x2' + } {{CREATE VIRTUAL TABLE "x2" USING tcl(tcl_command)}} + + do_execsql_test 7.1 { + CREATE TABLE ddd(db, sql, zOld, zNew, bTemp); + INSERT INTO ddd VALUES( + 'main', 'CREATE TABLE x1(i INTEGER, t TEXT)', 'ddd', NULL, 0 + ), ( + 'main', 'CREATE TABLE x1(i INTEGER, t TEXT)', NULL, 'eee', 0 + ), ( + 'main', NULL, 'ddd', 'eee', 0 + ); + } {} + + do_execsql_test 7.2 { + SELECT + sqlite_rename_table(db, 0, 0, sql, zOld, zNew, bTemp) + FROM ddd; + } {{} {} {}} +} + +#------------------------------------------------------------------------- +# +reset_db +forcedelete test.db2 +do_execsql_test 8.1 { + ATTACH 'test.db2' AS aux; + PRAGMA foreign_keys = on; + CREATE TABLE aux.p1(a INTEGER PRIMARY KEY, b); + CREATE TABLE aux.c1(x INTEGER PRIMARY KEY, y REFERENCES p1(a)); + INSERT INTO aux.p1 VALUES(1, 1); + INSERT INTO aux.p1 VALUES(2, 2); + INSERT INTO aux.c1 VALUES(NULL, 2); + CREATE TABLE aux.c2(x INTEGER PRIMARY KEY, y REFERENCES c1(a)); +} + +do_execsql_test 8.2 { + ALTER TABLE aux.p1 RENAME TO ppp; +} + +do_execsql_test 8.2 { + INSERT INTO aux.c1 VALUES(NULL, 1); + SELECT sql FROM aux.sqlite_master WHERE name = 'c1'; +} {{CREATE TABLE c1(x INTEGER PRIMARY KEY, y REFERENCES "ppp"(a))}} + +reset_db +do_execsql_test 9.0 { + CREATE TABLE t1(a, b, c); + CREATE VIEW v1 AS SELECT * FROM t2; +} +do_catchsql_test 9.1 { + ALTER TABLE t1 RENAME TO t3; +} {1 {error in view v1: no such table: main.t2}} +do_execsql_test 9.2 { + DROP VIEW v1; + CREATE TRIGGER tr AFTER INSERT ON t1 BEGIN + INSERT INTO t2 VALUES(new.a); + END; +} +do_catchsql_test 9.3 { + ALTER TABLE t1 RENAME TO t3; +} {1 {error in trigger tr: no such table: main.t2}} + +forcedelete test.db2 +do_execsql_test 9.4 { + DROP TRIGGER tr; + + ATTACH 'test.db2' AS aux; + CREATE TRIGGER tr AFTER INSERT ON t1 WHEN new.a IS NULL BEGIN SELECT 1, 2, 3; END; + + CREATE TABLE aux.t1(x); + CREATE TEMP TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END; +} +do_execsql_test 9.5 { + ALTER TABLE main.t1 RENAME TO t3; +} +do_execsql_test 9.6 { + SELECT sql FROM sqlite_temp_master; + SELECT sql FROM sqlite_master WHERE type='trigger'; +} { + {CREATE TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END} + {CREATE TRIGGER tr AFTER INSERT ON "t3" WHEN new.a IS NULL BEGIN SELECT 1, 2, 3; END} +} + +#------------------------------------------------------------------------- +reset_db +ifcapable fts5 { + do_execsql_test 10.0 { + CREATE VIRTUAL TABLE fff USING fts5(x, y, z); + } + + do_execsql_test 10.1 { + BEGIN; + INSERT INTO fff VALUES('a', 'b', 'c'); + ALTER TABLE fff RENAME TO ggg; + COMMIT; + } + + do_execsql_test 10.2 { + SELECT * FROM ggg; + } {a b c} +} + +#------------------------------------------------------------------------- +reset_db +forcedelete test.db2 +db func trigger trigger +set ::trigger [list] +proc trigger {args} { + lappend ::trigger $args +} +do_execsql_test 11.0 { + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.t1(a, b, c); + CREATE TABLE main.t1(a, b, c); + CREATE TEMP TRIGGER tr AFTER INSERT ON aux.t1 BEGIN + SELECT trigger(new.a, new.b, new.c); + END; +} + +do_execsql_test 11.1 { + INSERT INTO main.t1 VALUES(1, 2, 3); + INSERT INTO aux.t1 VALUES(4, 5, 6); +} +do_test 11.2 { set ::trigger } {{4 5 6}} + +do_execsql_test 11.3 { + SELECT name, tbl_name FROM sqlite_temp_master; +} {tr t1} + +do_execsql_test 11.4 { + ALTER TABLE main.t1 RENAME TO t2; + SELECT name, tbl_name FROM sqlite_temp_master; +} {tr t1} + +do_execsql_test 11.5 { + ALTER TABLE aux.t1 RENAME TO t2; + SELECT name, tbl_name FROM sqlite_temp_master; +} {tr t2} + +do_execsql_test 11.6 { + INSERT INTO aux.t2 VALUES(7, 8, 9); +} +do_test 11.7 { set ::trigger } {{4 5 6} {7 8 9}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 12.0 { + CREATE TABLE t1(a); + CREATE TABLE t2(w); + CREATE TRIGGER temp.r1 AFTER INSERT ON main.t2 BEGIN + INSERT INTO t1(a) VALUES(new.w); + END; + CREATE TEMP TABLE t2(x); +} + +do_execsql_test 12.1 { + ALTER TABLE main.t2 RENAME TO t3; +} + +do_execsql_test 12.2 { + INSERT INTO t3 VALUES('WWW'); + SELECT * FROM t1; +} {WWW} + + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 13.0 { + CREATE TABLE t1(x, y); + CREATE TABLE t2(a, b); + CREATE TABLE log(c); + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO log SELECT y FROM t1, t2; + END; +} + +do_execsql_test 13.1 { + INSERT INTO t1 VALUES(1, 2); +} + +do_catchsql_test 13.2 { + ALTER TABLE t2 RENAME b TO y; +} {1 {error in trigger tr1 after rename: ambiguous column name: y}} + +#------------------------------------------------------------------------- +reset_db + +ifcapable rtree { + do_execsql_test 14.0 { + CREATE VIRTUAL TABLE rt USING rtree(id, minx, maxx, miny, maxy); + + CREATE TABLE "mytable" ( "fid" INTEGER PRIMARY KEY, "geom" BLOB); + + CREATE TRIGGER tr1 AFTER UPDATE OF "geom" ON "mytable" + WHEN OLD."fid" = NEW."fid" AND NEW."geom" IS NULL BEGIN + DELETE FROM rt WHERE id = OLD."fid"; + END; + + INSERT INTO mytable VALUES(1, X'abcd'); + } + + do_execsql_test 14.1 { + UPDATE mytable SET geom = X'1234' + } + + do_execsql_test 14.2 { + ALTER TABLE mytable RENAME TO mytable_renamed; + } + + do_execsql_test 14.3 { + CREATE TRIGGER tr2 AFTER INSERT ON mytable_renamed BEGIN + DELETE FROM rt WHERE id=(SELECT min(id) FROM rt); + END; + } + + do_execsql_test 14.4 { + ALTER TABLE mytable_renamed RENAME TO mytable2; + } +} + +reset_db +do_execsql_test 14.5 { + CREATE TABLE t1(a, b, c); + CREATE VIEW v1 AS SELECT * FROM t1; + CREATE TRIGGER xyz AFTER INSERT ON t1 BEGIN + SELECT a, b FROM v1; + END; +} +do_execsql_test 14.6 { + ALTER TABLE t1 RENAME TO tt1; +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 15.0 { + CREATE TABLE t1(a integer NOT NULL PRIMARY KEY); + CREATE VIEW v1 AS SELECT a FROM t1; + CREATE TRIGGER tr1 INSTEAD OF INSERT ON v1 BEGIN + UPDATE t1 SET a = NEW.a; + END; + CREATE TRIGGER tr2 INSTEAD OF INSERT ON v1 BEGIN + SELECT new.a; + END; + CREATE TABLE t2 (b); +} + +do_execsql_test 15.1 { + INSERT INTO v1 VALUES(1); + ALTER TABLE t2 RENAME TO t3; +} + +do_execsql_test 15.2 { + CREATE TABLE x(f1 integer NOT NULL); + CREATE VIEW y AS SELECT f1 AS f1 FROM x; + CREATE TRIGGER t INSTEAD OF UPDATE OF f1 ON y BEGIN + UPDATE x SET f1 = NEW.f1; + END; + CREATE TABLE z (f1 integer NOT NULL PRIMARY KEY); + ALTER TABLE z RENAME TO z2; +} + +do_execsql_test 15.3 { + INSERT INTO x VALUES(1), (2), (3); + ALTER TABLE x RENAME f1 TO f2; + SELECT * FROM x; +} {1 2 3} + +do_execsql_test 15.4 { + UPDATE y SET f1 = 'x' WHERE f1 = 1; + SELECT * FROM x; +} {x x x} + +do_execsql_test 15.5 { + SELECT sql FROM sqlite_master WHERE name = 'y'; +} {{CREATE VIEW y AS SELECT f2 AS f1 FROM x}} + + +finish_test + diff --git a/test/altertab2.test b/test/altertab2.test new file mode 100644 index 0000000000..5656def81a --- /dev/null +++ b/test/altertab2.test @@ -0,0 +1,46 @@ +# 2018 September 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix altertab + +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} + +ifcapable fts5 { + do_execsql_test 1.0 { + CREATE TABLE rr(a, b); + CREATE VIRTUAL TABLE ff USING fts5(a, b); + CREATE TRIGGER tr1 AFTER INSERT ON rr BEGIN + INSERT INTO ff VALUES(new.a, new.b); + END; + INSERT INTO rr VALUES('hello', 'world'); + SELECT * FROM ff; + } {hello world} + + do_execsql_test 1.1 { + ALTER TABLE ff RENAME TO ffff; + } + + do_execsql_test 1.2 { + INSERT INTO rr VALUES('in', 'tcl'); + SELECT * FROM ffff; + } {hello world in tcl} +} + + +finish_test + diff --git a/test/analyze.test b/test/analyze.test index af277cc835..f3293b2917 100644 --- a/test/analyze.test +++ b/test/analyze.test @@ -349,7 +349,7 @@ ifcapable stat4||stat3 { # This test corrupts the database file so it must be the last test # in the series. # -do_test analyze-99.1 { +do_test analyze-5.99 { execsql { PRAGMA writable_schema=on; UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1'; @@ -361,4 +361,20 @@ do_test analyze-99.1 { } } {1 {malformed database schema (sqlite_stat1)}} +# Verify that tables whose names begin with "sqlite" but not +# "sqlite_" are analyzed. +# +db close +sqlite3 db :memory: +do_execsql_test analyze-6.1 { + CREATE TABLE sqliteDemo(a); + INSERT INTO sqliteDemo(a) VALUES(1),(2),(3),(4),(5); + CREATE TABLE SQLiteDemo2(a INTEGER PRIMARY KEY AUTOINCREMENT); + INSERT INTO SQLiteDemo2 SELECT * FROM sqliteDemo; + CREATE TABLE t1(b); + INSERT INTO t1(b) SELECT a FROM sqliteDemo; + ANALYZE; + SELECT tbl FROM sqlite_stat1 WHERE idx IS NULL ORDER BY tbl; +} {SQLiteDemo2 sqliteDemo t1} + finish_test diff --git a/test/analyze3.test b/test/analyze3.test index 3e721a0877..b7b324a868 100644 --- a/test/analyze3.test +++ b/test/analyze3.test @@ -118,10 +118,10 @@ do_execsql_test analyze3-1.1.x { # do_eqp_test analyze3-1.1.2 { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x? AND x0 AND x<1100 -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} # 2017-06-26: Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables # the use of bound parameters by STAT4 @@ -131,27 +131,27 @@ unset -nocomplain l unset -nocomplain u do_eqp_test analyze3-1.1.3.100 { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x? AND x$l AND x<$u -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x? AND x$l AND x<$u -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} db cache flush sqlite3_db_config db ENABLE_QPSG 1 do_eqp_test analyze3-1.1.3.103 { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x? AND x$l AND x<$u -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} do_test analyze3-1.1.4 { sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 } @@ -201,10 +201,10 @@ do_execsql_test analyze3-2.1.x { } {200 990} do_eqp_test analyze3-1.2.2 { SELECT sum(y) FROM t2 WHERE x>1 AND x<2 -} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x? AND x0 AND x<99 -} {0 0 0 {SCAN TABLE t2}} +} {SCAN TABLE t2} do_test analyze3-1.2.4 { sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 } @@ -253,10 +253,10 @@ do_execsql_test analyze3-1.3.x { } {99 1000} do_eqp_test analyze3-1.3.2 { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 -} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x? AND x0 AND x<1100 -} {0 0 0 {SCAN TABLE t3}} +} {SCAN TABLE t3} do_test analyze3-1.3.4 { sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 } @@ -308,10 +308,10 @@ do_test analyze3-2.1 { } {} do_eqp_test analyze3-2.2 { SELECT count(a) FROM t1 WHERE b LIKE 'a%' -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b? AND b 'w' AND c = 13; -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}} +} {SEARCH TABLE t1 USING INDEX i2 (c=?)} #----------------------------------------------------------------------------- # 2015-04-20. diff --git a/test/analyze4.test b/test/analyze4.test index 974ed89a86..9fc98aa8f2 100644 --- a/test/analyze4.test +++ b/test/analyze4.test @@ -38,7 +38,7 @@ do_test analyze4-1.0 { # Should choose the t1a index since it is more specific than t1b. db eval {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=5 AND b IS NULL} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} # Verify that the t1b index shows that it does not narrow down the # search any at all. diff --git a/test/analyze6.test b/test/analyze6.test index 31ace8eda5..34d00f56ec 100644 --- a/test/analyze6.test +++ b/test/analyze6.test @@ -61,14 +61,18 @@ do_test analyze6-1.0 { # do_test analyze6-1.1 { eqp {SELECT count(*) FROM ev, cat WHERE x=y} -} {0 0 1 {SCAN TABLE cat USING COVERING INDEX catx} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?)}} +} {/*SCAN TABLE cat USING COVERING INDEX catx*SEARCH TABLE ev USING COVERING INDEX evy (y=?)*/} # The same plan is chosen regardless of the order of the tables in the # FROM clause. # -do_test analyze6-1.2 { - eqp {SELECT count(*) FROM cat, ev WHERE x=y} -} {0 0 0 {SCAN TABLE cat USING COVERING INDEX catx} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?)}} +do_eqp_test analyze6-1.2 { + SELECT count(*) FROM cat, ev WHERE x=y +} { + QUERY PLAN + |--SCAN TABLE cat USING COVERING INDEX catx + `--SEARCH TABLE ev USING COVERING INDEX evy (y=?) +} # Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30 @@ -82,26 +86,26 @@ do_test analyze6-2.1 { ANALYZE; } eqp {SELECT * FROM t201 WHERE z=5} -} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}} +} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/} do_test analyze6-2.2 { eqp {SELECT * FROM t201 WHERE y=5} -} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}} +} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/} do_test analyze6-2.3 { eqp {SELECT * FROM t201 WHERE x=5} -} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}} +} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/} do_test analyze6-2.4 { execsql { INSERT INTO t201 VALUES(1,2,3),(2,3,4),(3,4,5); ANALYZE t201; } eqp {SELECT * FROM t201 WHERE z=5} -} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}} +} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/} do_test analyze6-2.5 { eqp {SELECT * FROM t201 WHERE y=5} -} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}} +} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/} do_test analyze6-2.6 { eqp {SELECT * FROM t201 WHERE x=5} -} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}} +} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/} do_test analyze6-2.7 { execsql { INSERT INTO t201 VALUES(4,5,7); @@ -111,12 +115,12 @@ do_test analyze6-2.7 { ANALYZE t201; } eqp {SELECT * FROM t201 WHERE z=5} -} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}} +} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/} do_test analyze6-2.8 { eqp {SELECT * FROM t201 WHERE y=5} -} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}} +} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/} do_test analyze6-2.9 { eqp {SELECT * FROM t201 WHERE x=5} -} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}} +} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/} finish_test diff --git a/test/analyze7.test b/test/analyze7.test index 76664546a5..d6da6c1510 100644 --- a/test/analyze7.test +++ b/test/analyze7.test @@ -37,13 +37,13 @@ do_test analyze7-1.0 { WHERE value BETWEEN 1 AND 256; EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123; } -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test analyze7-1.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test analyze7-1.2 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} # Run an analyze on one of the three indices. Verify that this # effects the row-count estimate on the one query that uses that @@ -53,20 +53,20 @@ do_test analyze7-2.0 { execsql {ANALYZE t1a;} db cache flush execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test analyze7-2.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test analyze7-2.2 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} # Verify that since the query planner now things that t1a is more # selective than t1b, it prefers to use t1a. # do_test analyze7-2.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} # Run an analysis on another of the three indices. Verify that this # new analysis works and does not disrupt the previous analysis. @@ -75,40 +75,40 @@ do_test analyze7-3.0 { execsql {ANALYZE t1cd;} db cache flush; execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test analyze7-3.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test analyze7-3.2.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} ifcapable stat4||stat3 { # If ENABLE_STAT4 is defined, SQLite comes up with a different estimated # row count for (c=2) than it does for (c=?). do_test analyze7-3.2.2 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}} + } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} } else { # If ENABLE_STAT4 is not defined, the expected row count for (c=2) is the # same as that for (c=?). do_test analyze7-3.2.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}} + } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} } do_test analyze7-3.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} ifcapable {!stat4 && !stat3} { do_test analyze7-3.4 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123} - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}} + } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test analyze7-3.5 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123} - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} + } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} } do_test analyze7-3.6 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)*/} finish_test diff --git a/test/analyze8.test b/test/analyze8.test index 1079e68080..daa83ef427 100644 --- a/test/analyze8.test +++ b/test/analyze8.test @@ -61,25 +61,25 @@ do_test 1.0 { # do_test 1.1 { eqp {SELECT * FROM t1 WHERE a=100 AND b=55} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test 1.2 { eqp {SELECT * FROM t1 WHERE a=99 AND b=55} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test 1.3 { eqp {SELECT * FROM t1 WHERE a=101 AND b=55} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test 1.4 { eqp {SELECT * FROM t1 WHERE a=100 AND b=56} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test 1.5 { eqp {SELECT * FROM t1 WHERE a=99 AND b=56} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test 1.6 { eqp {SELECT * FROM t1 WHERE a=101 AND b=56} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}} +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test 2.1 { eqp {SELECT * FROM t1 WHERE a=100 AND b BETWEEN 50 AND 54} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b? AND b? AND b? AND b? AND c? AND c? AND c? AND c? AND b? AND b=? term. Better than # (a<20) but not as good as (a<10). do_eqp_test 25.4.1 { SELECT * FROM t6 WHERE a < 10 AND (b BETWEEN ? AND 60) - } { - 0 0 0 {SEARCH TABLE t6 USING INDEX aa (a? AND b? AND b25 AND z=?; -} { - 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)} -} +} {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)} finish_test diff --git a/test/analyzeA.test b/test/analyzeA.test index a2da10edff..afcbe84b83 100644 --- a/test/analyzeA.test +++ b/test/analyzeA.test @@ -136,10 +136,10 @@ foreach {tn analyze_cmd} { do_eqp_test 1.$tn.2.5 { SELECT * FROM t1 WHERE b = 31 AND c = 0; - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}} + } {SEARCH TABLE t1 USING INDEX t1b (b=?)} do_eqp_test 1.$tn.2.6 { SELECT * FROM t1 WHERE b = 125 AND c = 16; - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?)}} + } {SEARCH TABLE t1 USING INDEX t1c (c=?)} do_execsql_test 1.$tn.3.1 { SELECT count(*) FROM t1 WHERE b BETWEEN 0 AND 50 @@ -156,31 +156,31 @@ foreach {tn analyze_cmd} { do_eqp_test 1.$tn.3.5 { SELECT * FROM t1 WHERE b BETWEEN 0 AND 50 AND c BETWEEN 0 AND 50 - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b? AND b? AND c? AND c? AND b? AND b? AND b? AND b? AND c? AND c? AND c? AND c0} { + incr ::at_fail -1 + if {$::at_fail==0} { + incr ::at_nfail + return SQLITE_IOERR + } elseif {$method=="xFileControl" && $z=="COMMIT_ATOMIC_WRITE"} { + set ::at_fail 0 + } + } + return SQLITE_OK +} + +testvfs tvfs -default 1 +tvfs script at_vfs_callback +tvfs filter {xFileControl xWrite} + +faultsim_save_and_close + +do_one_faultsim_test 2.0 {*}$setup -prep { + faultsim_restore_and_reopen +} -body { + execsql { + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 ) + INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s; + } +} -test { + faultsim_test_result {0 {}} + + set res [execsql {SELECT count(*) FROM t1; PRAGMA integrity_check}] + if {$res!="200 ok"} { + error "expected {200 ok}, got $res" + } +} + +db close +tvfs delete + +finish_test diff --git a/test/atrc.c b/test/atrc.c new file mode 100644 index 0000000000..c6e4ce3d05 --- /dev/null +++ b/test/atrc.c @@ -0,0 +1,150 @@ +/* +** This program generates a script that stresses the ALTER TABLE statement. +** Compile like this: +** +** gcc -g -c sqlite3.c +** gcc -g -o atrc atrc.c sqlite3.o -ldl -lpthread +** +** Run the program this way: +** +** ./atrc DATABASE | ./sqlite3 DATABASE +** +** This program "atrc" generates a script that can be fed into an ordinary +** command-line shell. The script performs many ALTER TABLE statements, +** runs ".schema --indent" and "PRAGMA integrity_check;", does more +** ALTER TABLE statements to restore the original schema, and then +** runs "PRAGMA integrity_check" again. Every table and column has its +** name changed. The entire script is contained within BEGIN...ROLLBACK +** so that no changes are ever actually made to the database. +*/ +#include "sqlite3.h" +#include + +/* +** Generate the text of ALTER TABLE statements that will rename +** every column in table zTable to a generic name composed from +** zColPrefix and a sequential number. The generated text is +** appended pConvert. If pUndo is not NULL, then SQL text that +** will undo the change is appended to pUndo. +** +** The table to be converted must be in the "main" schema. +*/ +int rename_all_columns_of_table( + sqlite3 *db, /* Database connection */ + const char *zTab, /* Table whose columns should all be renamed */ + const char *zColPrefix, /* Prefix for new column names */ + sqlite3_str *pConvert, /* Append ALTER TABLE statements here */ + sqlite3_str *pUndo /* SQL to undo the change, if not NULL */ +){ + sqlite3_stmt *pStmt; + int rc; + int cnt = 0; + + rc = sqlite3_prepare_v2(db, + "SELECT name FROM pragma_table_info(?1);", + -1, &pStmt, 0); + if( rc ) return rc; + sqlite3_bind_text(pStmt, 1, zTab, -1, SQLITE_STATIC); + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + const char *zCol = (const char*)sqlite3_column_text(pStmt, 0); + cnt++; + sqlite3_str_appendf(pConvert, + "ALTER TABLE \"%w\" RENAME COLUMN \"%w\" TO \"%w%d\";\n", + zTab, zCol, zColPrefix, cnt + ); + if( pUndo ){ + sqlite3_str_appendf(pUndo, + "ALTER TABLE \"%w\" RENAME COLUMN \"%w%d\" TO \"%w\";\n", + zTab, zColPrefix, cnt, zCol + ); + } + } + sqlite3_finalize(pStmt); + return SQLITE_OK; +} + +/* Rename all tables and their columns in the main database +*/ +int rename_all_tables( + sqlite3 *db, /* Database connection */ + sqlite3_str *pConvert, /* Append SQL to do the rename here */ + sqlite3_str *pUndo /* Append SQL to undo the rename here */ +){ + sqlite3_stmt *pStmt; + int rc; + int cnt = 0; + + rc = sqlite3_prepare_v2(db, + "SELECT name FROM sqlite_master WHERE type='table'" + " AND name NOT LIKE 'sqlite_%';", + -1, &pStmt, 0); + if( rc ) return rc; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + const char *zTab = (const char*)sqlite3_column_text(pStmt, 0); + char *zNewTab; + char zPrefix[2]; + + zPrefix[0] = (cnt%26) + 'a'; + zPrefix[1] = 0; + zNewTab = sqlite3_mprintf("tx%d", ++cnt); + if( pUndo ){ + sqlite3_str_appendf(pUndo, + "ALTER TABLE \"%s\" RENAME TO \"%w\";\n", + zNewTab, zTab + ); + } + rename_all_columns_of_table(db, zTab, zPrefix, pConvert, pUndo); + sqlite3_str_appendf(pConvert, + "ALTER TABLE \"%w\" RENAME TO \"%s\";\n", + zTab, zNewTab + ); + sqlite3_free(zNewTab); + } + sqlite3_finalize(pStmt); + return SQLITE_OK; +} + +/* +** Generate a script that does this: +** +** (1) Start a transaction +** (2) Rename all tables and columns to use generic names. +** (3) Print the schema after this rename +** (4) Run pragma integrity_check +** (5) Do more ALTER TABLE statements to change the names back +** (6) Run pragma integrity_check again +** (7) Rollback the transaction +*/ +int main(int argc, char **argv){ + sqlite3 *db; + int rc; + sqlite3_str *pConvert; + sqlite3_str *pUndo; + char *zDbName; + char *zSql1, *zSql2; + if( argc!=2 ){ + fprintf(stderr, "Usage: %s DATABASE\n", argv[0]); + } + zDbName = argv[1]; + rc = sqlite3_open(zDbName, &db); + if( rc ){ + fprintf(stderr, "sqlite3_open() returns %d\n", rc); + return 1; + } + pConvert = sqlite3_str_new(db); + pUndo = sqlite3_str_new(db); + rename_all_tables(db, pConvert, pUndo); + zSql1 = sqlite3_str_finish(pConvert); + zSql2 = sqlite3_str_finish(pUndo); + sqlite3_close(db); + printf("BEGIN;\n"); + printf("%s", zSql1); + sqlite3_free(zSql1); + printf(".schema --indent\n"); + printf("PRAGMA integrity_check;\n"); + printf("%s", zSql2); + sqlite3_free(zSql2); + printf("PRAGMA integrity_check;\n"); + printf("ROLLBACK;\n"); + return 0; +} diff --git a/test/attach2.test b/test/attach2.test index 741f959372..eb87b60f63 100644 --- a/test/attach2.test +++ b/test/attach2.test @@ -378,8 +378,7 @@ do_test attach2-6.2 { } } {0 {}} -# EVIDENCE-OF: R-59740-55581 This statement will fail if SQLite is in -# the middle of a transaction. +# As of version 3.21.0: it is ok to DETACH from within a transaction # do_test attach2-6.3 { catchsql { diff --git a/test/attachmalloc.test b/test/attachmalloc.test index 7fee1e1b2a..7a82f41f64 100644 --- a/test/attachmalloc.test +++ b/test/attachmalloc.test @@ -18,7 +18,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -ifcapable !memdebug||!attach { +ifcapable !attach { finish_test return } diff --git a/test/auth.test b/test/auth.test index 2487e568b2..354acba64a 100644 --- a/test/auth.test +++ b/test/auth.test @@ -2133,6 +2133,75 @@ ifcapable {cte} { } {1 {not authorized}} } ;# ifcapable cte +# +# db eval {SELECT sql FROM temp.sqlite_master} {puts "TEMP: $sql;"} +# db eval {SELECT sql FROM main.sqlite_master} {puts "MAIN: $sql;"} +# +# MAIN: CREATE TABLE "t2"(a,b,c); +# MAIN: CREATE TABLE t4(a,b,c); +# MAIN: CREATE INDEX t4i1 ON t4(a); +# MAIN: CREATE INDEX t4i2 ON t4(b,a,c); +# MAIN: CREATE TABLE sqlite_stat1(tbl,idx,stat); +# MAIN: CREATE TABLE t1(a,b); +# +ifcapable altertable&&vtab { + do_test 1.350 { + proc auth {code arg1 arg2 arg3 arg4 args} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_OK + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t1 RENAME COLUMN b TO bcdefg; + } + } {0 {}} + do_execsql_test auth-1.351 { + SELECT name FROM pragma_table_info('t1') ORDER BY cid; + } {a bcdefg} + do_test auth-1.352 { + set authargs + } {main t1 {} {}} + do_test 1.353 { + proc auth {code arg1 arg2 arg3 arg4 args} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_IGNORE + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t1 RENAME COLUMN bcdefg TO b; + } + } {0 {}} + do_execsql_test auth-1.354 { + SELECT name FROM pragma_table_info('t1') ORDER BY cid; + } {a bcdefg} + do_test auth-1.355 { + set authargs + } {main t1 {} {}} + do_test 1.356 { + proc auth {code arg1 arg2 arg3 arg4 args} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_DENY + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t1 RENAME COLUMN bcdefg TO b; + } + } {1 {not authorized}} + do_execsql_test auth-1.356 { + SELECT name FROM pragma_table_info('t1') ORDER BY cid; + } {a bcdefg} + do_test auth-1.357 { + set authargs + } {main t1 {} {}} +} + + do_test auth-2.1 { proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="x"} { @@ -2529,7 +2598,8 @@ do_test auth-8.2 { # invocation with no column name specified, compilation fails. # set ::authargs [list] -proc auth {op a b c d} { +proc auth {op args} { + foreach {a b c d} $args break lappend ::authargs $op $a $b $c $d if {$op == "SQLITE_READ"} { return "SQLITE_DENY" } return "SQLITE_OK" diff --git a/test/autoinc.test b/test/autoinc.test index 8ac12b1772..75b16daa10 100644 --- a/test/autoinc.test +++ b/test/autoinc.test @@ -25,6 +25,11 @@ ifcapable {!autoinc} { return } +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + sqlite3_db_config_lookaside db 0 0 0 # The database is initially empty. @@ -675,6 +680,173 @@ do_execsql_test autoinc-10.1 { SELECT * FROM sqlite_sequence; } {t10a 888 t10b 888} +# 2018-04-21 autoincrement does not cause problems for upsert +# +do_execsql_test autoinc-11.1 { + CREATE TABLE t11(a INTEGER PRIMARY KEY AUTOINCREMENT,b UNIQUE); + INSERT INTO t11(a,b) VALUES(2,3),(5,6),(4,3),(1,2) + ON CONFLICT(b) DO UPDATE SET a=a+1000; + SELECT seq FROM sqlite_sequence WHERE name='t11'; +} {5} +# 2018-05-23 ticket d8dc2b3a58cd5dc2918a1d4acbba4676a23ada4c +# Does not crash if the sqlite_sequence table schema is missing +# or corrupt. +# +do_test autoinc-12.1 { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + CREATE TABLE fake_sequence(name TEXT PRIMARY KEY,seq) WITHOUT ROWID; + PRAGMA writable_schema=on; + UPDATE sqlite_master SET + sql=replace(sql,'fake_','sqlite_'), + name='sqlite_sequence', + tbl_name='sqlite_sequence' + WHERE name='fake_sequence'; + } + db close + sqlite3 db test.db + set res [catch {db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT); + INSERT INTO t1(b) VALUES('one'); + }} msg] + lappend res $msg +} {1 {database disk image is malformed}} +do_test autoinc-12.2 { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT); + INSERT INTO t1(b) VALUES('one'); + PRAGMA writable_schema=on; + UPDATE sqlite_master SET + sql=replace(sql,'sqlite_','x_'), + name='x_sequence', + tbl_name='x_sequence' + WHERE name='sqlite_sequence'; + } + db close + sqlite3 db test.db + set res [catch {db eval { + INSERT INTO t1(b) VALUES('two'); + }} msg] + lappend res $msg +} {1 {database disk image is malformed}} +ifcapable vtab { + set err "database disk image is malformed" +} else { + set err {malformed database schema (sqlite_sequence) - near "VIRTUAL": syntax error} +} +do_test autoinc-12.3 { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT); + INSERT INTO t1(b) VALUES('one'); + PRAGMA writable_schema=on; + UPDATE sqlite_master SET + sql='CREATE VIRTUAL TABLE sqlite_sequence USING sqlite_dbpage' + WHERE name='sqlite_sequence'; + } + db close + sqlite3 db test.db + set res [catch {db eval { + INSERT INTO t1(b) VALUES('two'); + }} msg] + lappend res $msg +} [list 1 $err] +do_test autoinc-12.4 { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT); + INSERT INTO t1(b) VALUES('one'); + CREATE TABLE fake(name TEXT PRIMARY KEY,seq) WITHOUT ROWID; + } + set root1 [db one {SELECT rootpage FROM sqlite_master + WHERE name='sqlite_sequence'}] + set root2 [db one {SELECT rootpage FROM sqlite_master + WHERE name='fake'}] + db eval { + PRAGMA writable_schema=on; + UPDATE sqlite_master SET rootpage=$root2 + WHERE name='sqlite_sequence'; + UPDATE sqlite_master SET rootpage=$root1 + WHERE name='fake'; + } + db close + sqlite3 db test.db + set res [catch {db eval { + INSERT INTO t1(b) VALUES('two'); + }} msg] + lappend res $msg +} {1 {database disk image is malformed}} +breakpoint +do_test autoinc-12.5 { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT); + INSERT INTO t1(b) VALUES('one'); + PRAGMA writable_schema=on; + UPDATE sqlite_master SET + sql='CREATE TABLE sqlite_sequence(x)' + WHERE name='sqlite_sequence'; + } + db close + sqlite3 db test.db + set res [catch {db eval { + INSERT INTO t1(b) VALUES('two'); + }} msg] + lappend res $msg +} {1 {database disk image is malformed}} +do_test autoinc-12.6 { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT); + INSERT INTO t1(b) VALUES('one'); + PRAGMA writable_schema=on; + UPDATE sqlite_master SET + sql='CREATE TABLE sqlite_sequence(x,y INTEGER PRIMARY KEY)' + WHERE name='sqlite_sequence'; + } + db close + sqlite3 db test.db + set res [catch {db eval { + INSERT INTO t1(b) VALUES('two'),('three'),('four'); + INSERT INTO t1(b) VALUES('five'); + PRAGMA integrity_check; + }} msg] + lappend res $msg +} {0 ok} +do_test autoinc-12.7 { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT); + INSERT INTO t1(b) VALUES('one'); + PRAGMA writable_schema=on; + UPDATE sqlite_master SET + sql='CREATE TABLE sqlite_sequence(y INTEGER PRIMARY KEY,x)' + WHERE name='sqlite_sequence'; + } + db close + sqlite3 db test.db + set res [catch {db eval { + INSERT INTO t1(b) VALUES('two'),('three'),('four'); + INSERT INTO t1(b) VALUES('five'); + PRAGMA integrity_check; + }} msg] + lappend res $msg +} {0 ok} finish_test diff --git a/test/autoindex1.test b/test/autoindex1.test index bf9eca84c2..1978b8df1d 100644 --- a/test/autoindex1.test +++ b/test/autoindex1.test @@ -177,35 +177,36 @@ do_execsql_test autoindex1-500 { INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t501',null,'1000000'); INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t502',null,'1000'); ANALYZE sqlite_master; - EXPLAIN QUERY PLAN +} +do_eqp_test autoindex1-500.1 { SELECT b FROM t501 WHERE t501.a IN (SELECT x FROM t502 WHERE y=?); } { - 0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)} - 0 0 0 {EXECUTE LIST SUBQUERY 1} - 1 0 0 {SCAN TABLE t502} + QUERY PLAN + |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) + `--LIST SUBQUERY + `--SCAN TABLE t502 } -do_execsql_test autoindex1-501 { - EXPLAIN QUERY PLAN +do_eqp_test autoindex1-501 { SELECT b FROM t501 WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b); } { - 0 0 0 {SCAN TABLE t501} - 0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} - 1 0 0 {SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)} + QUERY PLAN + |--SCAN TABLE t501 + `--CORRELATED LIST SUBQUERY + `--SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?) } -do_execsql_test autoindex1-502 { - EXPLAIN QUERY PLAN +do_eqp_test autoindex1-502 { SELECT b FROM t501 WHERE t501.a=123 AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b); } { - 0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)} - 0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} - 1 0 0 {SCAN TABLE t502} + QUERY PLAN + |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) + `--CORRELATED LIST SUBQUERY + `--SCAN TABLE t502 } - # The following code checks a performance regression reported on the # mailing list on 2010-10-19. The problem is that the nRowEst field # of ephermeral tables was not being initialized correctly and so no @@ -257,7 +258,8 @@ do_execsql_test autoindex1-600 { ON sheep (originating_flock); CREATE INDEX sheep_reg_flock_index ON sheep (registering_flock); - EXPLAIN QUERY PLAN +} +do_eqp_test autoindex1-600a { SELECT x.sheep_no, x.registering_flock, x.date_of_registration FROM sheep x LEFT JOIN (SELECT s.sheep_no, prev.flock_no, prev.owner_person_id, @@ -274,21 +276,26 @@ do_execsql_test autoindex1-600 { WHERE y.sheep_no IS NULL ORDER BY x.registering_flock; } { - 1 0 0 {SCAN TABLE sheep AS s} - 1 1 1 {SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date? AND owner_change_date? AND owner_change_date 34; } { - 0 0 1 {SEARCH TABLE v USING INDEX ve (e>?)} - 0 1 0 {SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)} + QUERY PLAN + |--SEARCH TABLE v USING INDEX ve (e>?) + `--SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?) } diff --git a/test/autoindex5.test b/test/autoindex5.test index 649ae123a4..aba546a1ec 100644 --- a/test/autoindex5.test +++ b/test/autoindex5.test @@ -84,8 +84,7 @@ do_execsql_test autoindex5-1.0 { # 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 +do_eqp_test autoindex5-1.1 { SELECT st.bug_name, (SELECT ALL debian_cve.bug FROM debian_cve @@ -103,7 +102,7 @@ do_execsql_test autoindex5-1.1 { 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=/} +} {SEARCH SUBQUERY * USING AUTOMATIC COVERING INDEX (bug_name=?)} #------------------------------------------------------------------------- # Test that ticket [8a2adec1] has been fixed. diff --git a/test/avtrans.test b/test/avtrans.test index 17a2860649..6fc4a3e393 100644 --- a/test/avtrans.test +++ b/test/avtrans.test @@ -22,7 +22,7 @@ source $testdir/tester.tcl # Create several tables to work with. # do_test avtrans-1.0 { - execsql { PRAGMA auto_vacuum=ON } + execsql { PRAGMA auto_vacuum=full } wal_set_journal_mode execsql { CREATE TABLE one(a int PRIMARY KEY, b text); @@ -32,6 +32,7 @@ do_test avtrans-1.0 { SELECT b FROM one ORDER BY a; } } {one two three} +do_test avtrans-1.0.1 { execsql { PRAGMA auto_vacuum } } 1 do_test avtrans-1.1 { execsql { CREATE TABLE two(a int PRIMARY KEY, b text); diff --git a/test/bestindex1.test b/test/bestindex1.test index f90f96bf44..1d79c73166 100644 --- a/test/bestindex1.test +++ b/test/bestindex1.test @@ -51,16 +51,11 @@ do_execsql_test 1.0 { do_eqp_test 1.1 { SELECT * FROM x1 WHERE a = 'abc' -} { - 0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!} -} +} {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!} do_eqp_test 1.2 { SELECT * FROM x1 WHERE a IN ('abc', 'def'); -} { - 0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!} - 0 0 0 {EXECUTE LIST SUBQUERY 1} -} +} {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!} #------------------------------------------------------------------------- # @@ -145,24 +140,24 @@ foreach {tn mode} { } {1 4} set plan(use) { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'} - 0 0 0 {EXECUTE LIST SUBQUERY 1} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%' + `--USE TEMP B-TREE FOR ORDER BY } set plan(omit) { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'} - 0 0 0 {EXECUTE LIST SUBQUERY 1} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%' + `--USE TEMP B-TREE FOR ORDER BY } set plan(use2) { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x} - 0 0 0 {EXECUTE LIST SUBQUERY 1} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 2.2.$mode.6 { SELECT rowid FROM t1 WHERE a IN ('one', 'four') ORDER BY +rowid - } $plan($mode) + } [string map {"\n " "\n"} $plan($mode)] } # 2016-04-09. diff --git a/test/bestindex2.test b/test/bestindex2.test index 8bc3fbc323..c17665f6f5 100644 --- a/test/bestindex2.test +++ b/test/bestindex2.test @@ -89,40 +89,40 @@ do_execsql_test 1.0 { do_eqp_test 1.1 { SELECT * FROM t1 WHERE a='abc' -} { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)} -} +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)} + do_eqp_test 1.2 { SELECT * FROM t1 WHERE a='abc' AND b='def' -} { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=? AND b=?)} -} +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=? AND b=?)} + do_eqp_test 1.3 { SELECT * FROM t1 WHERE a='abc' AND a='def' -} { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)} -} +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)} + do_eqp_test 1.4 { SELECT * FROM t1,t2 WHERE c=a } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:} - 0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0: + `--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?) } do_eqp_test 1.5 { SELECT * FROM t1, t2 CROSS JOIN t3 WHERE t2.c = +t1.b AND t3.e=t2.d } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:} - 0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)} - 0 2 2 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0: + |--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?) + `--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?) } do_eqp_test 1.6 { SELECT * FROM t1, t2, t3 WHERE t2.c = +t1.b AND t3.e = t2.d } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:} - 0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)} - 0 2 2 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)} + QUERY PLAN + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0: + |--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?) + `--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?) } do_execsql_test 1.7.1 { @@ -132,10 +132,11 @@ do_eqp_test 1.7.2 { SELECT * FROM x1 CROSS JOIN t1, t2, t3 WHERE t1.a = t2.c AND t1.b = t3.e } { - 0 0 0 {SCAN TABLE x1} - 0 1 1 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:} - 0 2 2 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)} - 0 3 3 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)} + QUERY PLAN + |--SCAN TABLE x1 + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0: + |--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?) + `--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?) } finish_test diff --git a/test/bestindex3.test b/test/bestindex3.test index 70c60d66dd..4b125d4df0 100644 --- a/test/bestindex3.test +++ b/test/bestindex3.test @@ -79,28 +79,28 @@ do_execsql_test 1.0 { do_eqp_test 1.1 { SELECT * FROM t1 WHERE a LIKE 'abc'; -} { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?} -} +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?} do_eqp_test 1.2 { SELECT * FROM t1 WHERE a = 'abc'; -} { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?} -} +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?} do_eqp_test 1.3 { SELECT * FROM t1 WHERE a = 'abc' OR b = 'def'; } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?} - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?} + QUERY PLAN + `--MULTI-INDEX OR + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ? + `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ? } do_eqp_test 1.4 { SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def'; } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?} - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?} + QUERY PLAN + `--MULTI-INDEX OR + |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ? + `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ? } do_execsql_test 1.5 { @@ -147,10 +147,12 @@ ifcapable !icu { do_eqp_test 2.2 { SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def' - } { - 0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x? AND x1000} { execsql { COMMIT } db2 } + return 0 +} +db busy busy_handler + +do_test 3.3 { + catchsql { PRAGMA optimize } +} {0 {}} + +do_test 3.4 { + execsql { + BEGIN; + SELECT count(*) FROM sqlite_master; + } db2 +} {6} + +proc busy_handler {n} { return 1 } +do_test 3.5 { + catchsql { PRAGMA optimize } +} {0 {}} + +do_test 3.6 { + execsql { COMMIT } db2 + execsql { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO t1 SELECT i FROM s; + } + execsql { + BEGIN; + SELECT count(*) FROM sqlite_master; + } db2 +} {6} + +do_test 3.7 { + catchsql { PRAGMA optimize } +} {1 {database is locked}} + +proc busy_handler {n} { + if {$n>1000} { execsql { COMMIT } db2 } + return 0 +} +do_test 3.8 { + catchsql { PRAGMA optimize } +} {0 {}} + +} + finish_test diff --git a/test/capi2.test b/test/capi2.test index 39f50dd079..0680cf530c 100644 --- a/test/capi2.test +++ b/test/capi2.test @@ -163,7 +163,7 @@ do_test capi2-3.2 { sqlite3_prepare $DB {select bogus from } -1 TAIL } msg] lappend rc $msg $TAIL -} {1 {(1) near " ": syntax error} {}} +} {1 {(1) incomplete input} {}} do_test capi2-3.3 { set rc [catch { sqlite3_prepare $DB {;;;;select bogus from sqlite_master} -1 TAIL @@ -184,7 +184,7 @@ do_test capi2-3.5 { } {1 {(1) no such column: bogus} {;;x;}} do_test capi2-3.6 { set rc [catch { - sqlite3_prepare $DB {select 5/0} -1 TAIL + sqlite3_prepare $DB {select 5/0;} -1 TAIL } VM] lappend rc $TAIL } {0 {}} diff --git a/test/capi3.test b/test/capi3.test index becf1bf5db..4950ef245e 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -649,6 +649,18 @@ do_test capi3-5.33 { sqlite3_finalize $STMT } SQLITE_OK +# 2018-01-09: If a column is the last token if a string, the column name +# was not being set correctly, due to changes in check-in +# https://sqlite.org/src/info/0fdf97efe5df7455 +# +# This problem was detected by the community during beta-testing. +# +do_test capi3-5.34 { + set STMT [sqlite3_prepare $DB {SELECT :a, :b} -1 TAIL] + sqlite3_column_count $STMT +} 2 +check_header $STMT capi-5.35 {:a :b} {{} {}} +sqlite3_finalize $STMT set ::ENC [execsql {pragma encoding}] db close @@ -799,7 +811,6 @@ foreach {code english} $code2english { # Test the error message when a "real" out of memory occurs. if { [permutation] != "nofaultsim" } { -ifcapable memdebug { do_test capi3-10-1 { sqlite3 db test.db set DB [sqlite3_connection_pointer db] @@ -837,7 +848,6 @@ ifcapable memdebug { db close sqlite3_memdebug_fail -1 } -} # The following tests - capi3-11.* - test that a COMMIT or ROLLBACK # statement issued while there are still outstanding VMs that are part of diff --git a/test/capi3c.test b/test/capi3c.test index 5d889e3249..c275242459 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -757,7 +757,6 @@ foreach {code english} $code2english { # Test the error message when a "real" out of memory occurs. if { [permutation] != "nofaultsim" } { -ifcapable memdebug { do_test capi3c-10-1 { sqlite3 db test.db set DB [sqlite3_connection_pointer db] @@ -777,7 +776,6 @@ ifcapable memdebug { db close sqlite3_memdebug_fail -1 } -} # The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK # statement issued while there are still outstanding VMs that are part of diff --git a/test/cast.test b/test/cast.test index f47f4bb2bf..f43aa48560 100644 --- a/test/cast.test +++ b/test/cast.test @@ -343,4 +343,49 @@ do_test cast-4.4 { } } {0 abc 0.0 abc} +# Added 2018-01-26 +# +# EVIDENCE-OF: R-48741-32454 If the prefix integer is greater than +# +9223372036854775807 then the result of the cast is exactly +# +9223372036854775807. +do_execsql_test cast-5.1 { + SELECT CAST('9223372036854775808' AS integer); + SELECT CAST(' +000009223372036854775808' AS integer); + SELECT CAST('12345678901234567890123' AS INTEGER); +} {9223372036854775807 9223372036854775807 9223372036854775807} + +# EVIDENCE-OF: R-06028-16857 Similarly, if the prefix integer is less +# than -9223372036854775808 then the result of the cast is exactly +# -9223372036854775808. +do_execsql_test cast-5.2 { + SELECT CAST('-9223372036854775808' AS integer); + SELECT CAST('-9223372036854775809' AS integer); + SELECT CAST('-12345678901234567890123' AS INTEGER); +} {-9223372036854775808 -9223372036854775808 -9223372036854775808} + +# EVIDENCE-OF: R-33990-33527 When casting to INTEGER, if the text looks +# like a floating point value with an exponent, the exponent will be +# ignored because it is no part of the integer prefix. +# EVIDENCE-OF: R-24225-46995 For example, "(CAST '123e+5' AS INTEGER)" +# results in 123, not in 12300000. +do_execsql_test case-5.3 { + SELECT CAST('123e+5' AS INTEGER); + SELECT CAST('123e+5' AS NUMERIC); +} {123 12300000.0} + + +# The following does not have anything to do with the CAST operator, +# but it does deal with affinity transformations. +# +do_execsql_test case-6.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a NUMERIC); + INSERT INTO t1 VALUES + ('9000000000000000001'), + ('9000000000000000001 '), + (' 9000000000000000001'), + (' 9000000000000000001 '); + SELECT * FROM t1; +} {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001} + finish_test diff --git a/test/closure01.test b/test/closure01.test index 213ef4e966..ee3f2dd1d0 100644 --- a/test/closure01.test +++ b/test/closure01.test @@ -273,4 +273,23 @@ do_execsql_test 5.1 { ORDER BY id; } {8 9 10 11 12 13 14 15} +#------------------------------------------------------------------------- +# At one point the following join query was causing a malfunction in +# xBestIndex. +# +do_execsql_test 6.0 { + CREATE TABLE t4 ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + parent_id INTEGER + ); + CREATE VIRTUAL TABLE vt4 USING transitive_closure ( + idcolumn=id, parentcolumn=parent_id, tablename=t4 + ); +} + +do_execsql_test 6.1 { + SELECT * FROM t4, vt4 WHERE t4.id = vt4.root AND vt4.id=4 AND vt4.depth=2; +} + finish_test diff --git a/test/colname.test b/test/colname.test index 1497fc275c..f314f94f6e 100644 --- a/test/colname.test +++ b/test/colname.test @@ -378,5 +378,64 @@ do_test colname-9.210 { execsql2 {SELECT t1.a, v3.a AS n FROM t1 JOIN v3} } {a 1 n 3} +# 2017-12-23: Ticket https://www.sqlite.org/src/info/3b4450072511e621 +# Inconsistent column names in CREATE TABLE AS +# +# Verify that the names of columns in the created table of a CREATE TABLE AS +# are the same as the names of result columns in the SELECT statement. +# +do_execsql_test colname-9.300 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(aaa INT); + INSERT INTO t1(aaa) VALUES(123); +} +do_test colname-9.310 { + execsql2 {SELECT BBb FROM (SELECT aaa AS Bbb FROM t1)} +} {Bbb 123} +ifcapable vtab { + do_execsql_test colname-9.320 { + CREATE TABLE t2 AS SELECT BBb FROM (SELECT aaa AS Bbb FROM t1); + SELECT name FROM pragma_table_info('t2'); + } {Bbb} +} + +# Issue detected by OSSFuzz on 2017-12-24 (Christmas Eve) +# caused by check-in https://sqlite.org/src/info/6b2ff26c25 +# +# Prior to being fixed, the following CREATE TABLE was dereferencing +# a NULL pointer and segfaulting. +# +do_catchsql_test colname-9.400 { + CREATE TABLE t4 AS SELECT #0; +} {1 {near "#0": syntax error}} + +# Issue detected by OSSFuzz on 2017-12-25 (Christmas Day) +# also caused by check-in https://sqlite.org/src/info/6b2ff26c25 +# +# Prior to being fixed, the following CREATE TABLE caused an +# assertion fault. +# +do_catchsql_test colname-9.410 { + CREATE TABLE t5 AS SELECT RAISE(abort,a); +} {1 {RAISE() may only be used within a trigger-program}} + +# Make sure the quotation marks get removed from the column names +# when constructing a new table from an aggregate SELECT. +# Email from Juergen Palm on 2017-07-11. +# +do_execsql_test colname-10.100 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1("with space" TEXT); + DROP TABLE IF EXISTS t2; + CREATE TABLE t2 AS SELECT "with space" FROM t1; + PRAGMA table_info(t2); +} {0 {with space} TEXT 0 {} 0} +do_execsql_test colname-10.110 { + DROP TABLE IF EXISTS t3; + CREATE TABLE t3 AS SELECT "with space" FROM t1 GROUP BY 1; + PRAGMA table_info(t3); +} {0 {with space} TEXT 0 {} 0} + finish_test diff --git a/test/corrupt2.test b/test/corrupt2.test index 4b58da1cc1..9512d0f242 100644 --- a/test/corrupt2.test +++ b/test/corrupt2.test @@ -591,7 +591,7 @@ do_test 14.2 { do_execsql_test 14.3 { PRAGMA integrity_check; } {{*** in database main *** -Main freelist: free-page count in header is too small}} +Main freelist: size is 3 but should be 2}} # Use 2 of the free pages on the free-list. # @@ -603,7 +603,7 @@ do_execsql_test 14.4 { do_execsql_test 14.5 { PRAGMA integrity_check; } {{*** in database main *** -Page 3 is never used}} +Main freelist: size is 1 but should be 0}} finish_test diff --git a/test/corrupt3.test b/test/corrupt3.test index 85139420b8..3c911dadb6 100644 --- a/test/corrupt3.test +++ b/test/corrupt3.test @@ -67,8 +67,7 @@ do_test corrupt3-1.5 { integrity_check corrupt3-1.6 # Make the overflow chain loop back on itself. See if the -# corruption is detected. (Actually, the last pointer in -# an overflow chain is ignored, so this is not an error.) +# corruption is detected. # do_test corrupt3-1.7 { db close @@ -78,7 +77,12 @@ do_test corrupt3-1.7 { SELECT x FROM t1 } } [list 0 $bigstring] -integrity_check corrupt3-1.8 +do_test corrupt3-1.8 { + catchsql { + PRAGMA integrity_check + } +} {0 {{*** in database main *** +On tree page 2 cell 0: 2nd reference to page 3}}} # Change the pointer for the first page of the overflow # change to be a non-existant page. @@ -111,7 +115,7 @@ do_test corrupt3-1.12 { PRAGMA integrity_check } } {0 {{*** in database main *** -On tree page 2 cell 0: 1 of 1 pages missing from overflow list starting at 0 +On tree page 2 cell 0: overflow list length is 0 but should be 1 Page 3 is never used}}} finish_test diff --git a/test/corruptC.test b/test/corruptC.test index f404e4fb5b..7c6ffb8102 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -164,7 +164,7 @@ do_test corruptC-2.5 { catchsql {BEGIN; UPDATE t2 SET y='abcdef-uvwxyz'; ROLLBACK;} catchsql {PRAGMA integrity_check} } {0 {{*** in database main *** -On tree page 4 cell 19: Extends off end of page}}} +On tree page 4 cell 19: Extends off end of page} {database disk image is malformed}}} # {0 {{*** in database main *** # Corruption detected in cell 710 on page 4 diff --git a/test/corruptK.test b/test/corruptK.test index b20c2d8bf0..1694db1747 100644 --- a/test/corruptK.test +++ b/test/corruptK.test @@ -107,6 +107,121 @@ do_catchsql_test 2.3 { INSERT INTO t1 VALUES(randomblob(900)); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- + +ifcapable vtab { +if {[permutation]!="inmemory_journal"} { + + proc hex2blob {hex} { + # Split on newlines: + set bytes [list] + foreach l [split $hex "\n"] { + if {[string is space $l]} continue + set L [list] + foreach b [split $l] { + if {[string is xdigit $b] && [string length $b]==2} { + lappend L [expr "0x$b"] + } + } + if {[llength $L]!=16} { + error "Badly formed hex (1)" + } + set bytes [concat $bytes $L] + } + + binary format c* $bytes + } + + reset_db + db func hex2blob hex2blob + + do_execsql_test 3.1 { + PRAGMA page_size=1024; + CREATE TABLE t1(a, b, c); + CREATE TABLE t2(a, b, c); + CREATE TABLE t3(a, b, c); + CREATE TABLE t4(a, b, c); + CREATE TABLE t5(a, b, c); + } + + do_execsql_test 3.2 { + UPDATE sqlite_dbpage SET data = hex2blob(' + 000: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. + 010: 04 00 01 01 20 40 20 20 00 00 3e d9 00 00 00 06 .... @ ..>..... + 020: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ + 030: 0f 00 00 00 00 00 00 00 00 00 00 01 00 00 83 00 ................ + 040: 00 00 00 00 00 00 00 00 00 00 00 00 00 38 00 00 .............8.. + 050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3e d9 ..............>. + 060: 00 2d e6 07 0d 00 00 00 01 03 a0 00 03 e0 00 00 .-.............. + 070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 0a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 0d0: 00 00 00 00 00 c1 00 00 00 00 00 00 00 00 00 00 ................ + 0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 160: 00 83 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 180: 00 00 00 00 00 00 00 00 00 00 07 00 30 00 00 00 ............0... + 190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 1c0: 02 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 ................ + 1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 1f0: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 220: 00 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 230: 0c 00 00 00 00 00 00 60 00 00 00 06 00 00 c3 00 .......`........ + 240: 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 270: 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 290: 04 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 2b0: 00 00 00 00 83 00 8c 00 00 00 00 00 00 00 00 00 ................ + 2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 310: 00 78 00 00 00 00 00 00 00 00 00 00 00 00 70 00 .x............p. + 320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 340: 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 350: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00 .....h.......... + 360: 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 ................ + 370: 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 ................ + 380: 00 00 00 00 70 00 00 00 00 00 00 00 00 00 00 00 ....p........... + 390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 3a0: 5e 01 07 17 1b 1b 01 81 13 74 61 62 6c 65 73 65 ^........tablese + 3b0: 6e 73 6f 32 73 73 65 6e 73 6f 72 73 02 43 52 45 nso2ssensors.CRE + 3c0: 41 54 45 20 54 41 42 4c 45 20 73 65 6e 73 6f 72 ATE TABLE sensor + 3d0: 73 20 0a 20 20 24 20 20 20 20 20 20 20 20 20 20 s . $ + 3e0: b8 6e 61 6d 65 21 74 65 78 74 2c 20 79 61 6c 20 .name!text, yal + 3f0: 72 65 61 6c 2c 20 74 69 6d 65 20 74 65 78 74 29 real, time text) + ') WHERE pgno=1 + } + + db close + sqlite3 db test.db + + do_catchsql_test 3.3 { + PRAGMA integrity_check; + } {1 {database disk image is malformed}} + +} ;# [permutation]!="inmemory_journal" +} ;# ifcapable vtab diff --git a/test/cost.test b/test/cost.test index 9c10d821d9..5d23e0ed7b 100644 --- a/test/cost.test +++ b/test/cost.test @@ -24,8 +24,9 @@ do_execsql_test 1.1 { do_eqp_test 1.2 { SELECT e FROM t3, t4 WHERE b=c ORDER BY b, d; } { - 0 0 0 {SCAN TABLE t3 USING COVERING INDEX i3} - 0 1 1 {SEARCH TABLE t4 USING INDEX i4 (c=?)} + QUERY PLAN + |--SCAN TABLE t3 USING COVERING INDEX i3 + `--SEARCH TABLE t4 USING INDEX i4 (c=?) } @@ -38,9 +39,7 @@ do_execsql_test 2.1 { # if the index is a non-covering index. do_eqp_test 2.2 { SELECT * FROM t1 ORDER BY a; -} { - 0 0 0 {SCAN TABLE t1 USING INDEX i1} -} +} {SCAN TABLE t1 USING INDEX i1} do_execsql_test 3.1 { CREATE TABLE t5(a INTEGER PRIMARY KEY,b,c,d,e,f,g); @@ -57,10 +56,12 @@ do_eqp_test 3.2 { WHERE b IS NULL OR c IS NULL OR d IS NULL ORDER BY a; } { - 0 0 0 {SEARCH TABLE t5 USING INDEX t5b (b=?)} - 0 0 0 {SEARCH TABLE t5 USING INDEX t5c (c=?)} - 0 0 0 {SEARCH TABLE t5 USING INDEX t5d (d=?)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--MULTI-INDEX OR + | |--SEARCH TABLE t5 USING INDEX t5b (b=?) + | |--SEARCH TABLE t5 USING INDEX t5c (c=?) + | `--SEARCH TABLE t5 USING INDEX t5d (d=?) + `--USE TEMP B-TREE FOR ORDER BY } #------------------------------------------------------------------------- @@ -79,14 +80,11 @@ do_execsql_test 4.1 { } do_eqp_test 4.2 { SELECT * FROM t1 WHERE likelihood(a=?, 0.014) AND b BETWEEN ? AND ?; -} { - 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)} -} +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} + do_eqp_test 4.3 { SELECT * FROM t1 WHERE likelihood(a=?, 0.016) AND b BETWEEN ? AND ?; -} { - 0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b>? AND b? AND b? AND x? AND x? AND b? AND b=950 AND b<=1010) OR (b IS NULL AND c NOT NULL) ORDER BY a } { - 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b? AND b=1; UPDATE ab SET b = randstr(1000,1000) WHERE a>=1; } - list [file exists test.db-journal] [file exists test2.db-journal] - } {1 1} + } {persist persist} + if {[atomic_batch_write test.db]==0} { + do_test crash8.4.1.1 { + list [file exists test.db-journal] [file exists test2.db-journal] + } {1 1} + } do_test crash8-4.2 { execsql { @@ -346,7 +352,11 @@ ifcapable pragma { # Since the following tests (crash8-5.*) rely upon being able # to copy a file while open, they will not work on Windows. # -if {$::tcl_platform(platform)=="unix"} { +# They also depend on being able to copy the journal file, which +# is not created on F2FS file-systems that support atomic +# write. So do not run these tests in that case either. +# +if {$::tcl_platform(platform)=="unix" && [atomic_batch_write test.db]==0 } { for {set i 1} {$i < 10} {incr i} { catch { db close } forcedelete test.db test.db-journal diff --git a/test/csv01.test b/test/csv01.test index 8151c47714..f30f7ac9df 100644 --- a/test/csv01.test +++ b/test/csv01.test @@ -93,6 +93,7 @@ do_catchsql_test 3.2 { SELECT rowid, a FROM t3; } {1 {no such column: rowid}} +# Multi-column WITHOUT ROWID virtual tables may not be writable. do_catchsql_test 4.0 { DROP TABLE t3; CREATE VIRTUAL TABLE temp.t4 USING csv_wr( @@ -100,13 +101,60 @@ do_catchsql_test 4.0 { '1,2,3,4 5,6,7,8 9,10,11,12 -13,14,15,16 -', +13,14,15,16', columns=4, schema= - 'CREATE TABLE t3(a PRIMARY KEY,b TEXT,c TEXT,d TEXT) WITHOUT ROWID', + 'CREATE TABLE t3(a,b,c,d,PRIMARY KEY(a,b)) WITHOUT ROWID', testflags=1 ); } {1 {vtable constructor failed: t4}} +# WITHOUT ROWID tables with a single-column PRIMARY KEY may be writable. +do_catchsql_test 4.1 { + DROP TABLE IF EXISTS t4; + CREATE VIRTUAL TABLE temp.t4 USING csv_wr( + data= +'1,2,3,4 +5,6,7,8 +9,10,11,12 +13,14,15,16', + columns=4, + schema= + 'CREATE TABLE t3(a,b,c,d,PRIMARY KEY(b)) WITHOUT ROWID', + testflags=1 + ); +} {0 {}} + +do_catchsql_test 4.2 { + DROP TABLE IF EXISTS t5; + CREATE VIRTUAL TABLE temp.t5 USING csv_wr( + data= + '1,2,3,4 + 5,6,7,8 + 9,10,11,12 + 13,14,15,16', + columns=4, + schema= + 'CREATE TABLE t3(a,b,c,d) WITHOUT ROWID', + testflags=1 + ); +} {1 {vtable constructor failed: t5}} + +# 2018-04-24 +# Memory leak reported on the sqlite-users mailing list by Ralf Junker. +# +do_catchsql_test 4.3 { + CREATE VIRTUAL TABLE IF NOT EXISTS temp.t1 + USING csv(filename='FileDoesNotExist.csv'); +} {1 {cannot open 'FileDoesNotExist.csv' for reading}} + +# 2018-06-02 +# Problem with single-column CSV support reported on the mailing list +# by Trent W. Buck. +# +do_execsql_test 4.4 { + CREATE VIRTUAL TABLE temp.trent USING csv(data='1'); + SELECT * FROM trent; +} {1} + finish_test diff --git a/test/cursorhint2.test b/test/cursorhint2.test index 616235b376..a78d151b98 100644 --- a/test/cursorhint2.test +++ b/test/cursorhint2.test @@ -136,49 +136,69 @@ do_extract_hints_test 2.5 { x2 {EQ(c0,r[2])} } -do_extract_hints_test 2.6 { - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL) -} { - x2 {EQ(c0,r[2])} -} - -do_extract_hints_test 2.7 { - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL) -} { - x2 {EQ(c0,r[2])} -} - -do_extract_hints_test 2.8 { - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL -} { - x2 {EQ(c0,r[2])} -} - -do_extract_hints_test 2.9 { - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE CASE b WHEN 0 THEN 0 ELSE 1 END; -} { - x2 {EQ(c0,r[2])} -} - -do_extract_hints_test 2.10 { - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32 -} { - x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} -} - -ifcapable !icu { - # This test only works using the built-in LIKE, not the ICU LIKE extension. - do_extract_hints_test 2.11 { - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' +if {0} { + # These tests no longer work due to the LEFT-JOIN strength reduction + # optimization + do_extract_hints_test 2.6 { + SELECT * FROM x1 CROSS JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL) } { - x2 {AND(expr,EQ(c0,r[2]))} + x2 {EQ(c0,r[2])} + } + + do_extract_hints_test 2.7 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL) + } { + x2 {EQ(c0,r[2])} + } + + do_extract_hints_test 2.8 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL + } { + x2 {EQ(c0,r[2])} + } + + do_extract_hints_test 2.9 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) + WHERE CASE b WHEN 0 THEN 0 ELSE 1 END; + } { + x2 {EQ(c0,r[2])} + } + + do_extract_hints_test 2.10 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32 + } { + x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} + } + + ifcapable !icu { + # This test only works using the built-in LIKE, not the ICU LIKE extension. + do_extract_hints_test 2.11 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' + } { + x2 {AND(expr,EQ(c0,r[2]))} + } } } - + do_extract_hints_test 2.12 { SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1) } { x2 {EQ(c0,r[2])} } +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1 (i1 TEXT); + CREATE TABLE t2 (i2 TEXT UNIQUE); + INSERT INTO t1 VALUES('0'); + INSERT INTO t2 VALUES('0'); +} + +do_extract_hints_test 3.1 { + SELECT * FROM t1 CROSS JOIN t2 WHERE (t1.i1 = t2.i2) AND t2.i2 = 1; +} { + t1 {EQ(c0,r[1])} t2 EQ(c0,1) +} + + finish_test diff --git a/test/dataversion1.test b/test/dataversion1.test new file mode 100644 index 0000000000..55f7aada0c --- /dev/null +++ b/test/dataversion1.test @@ -0,0 +1,87 @@ +# 2018-07-18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test case for SQLITE_FCNTL_DATA_VERSION +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Construct a database and get its initial data version +sqlite3 db test.db +do_test dataversion1-100 { + db eval { + CREATE TABLE t1(x); + INSERT INTO t1(x) VALUES(99); + SELECT * FROM t1; + } +} {99} +set dv1 [file_control_data_version db main] + +# The data version does not change by ATTACH or by changes to +# other schemas within the same connection. +# +do_test dataversion1-101 { + db eval { + ATTACH ':memory:' AS aux1; + CREATE TABLE aux1.t2(y); + CREATE TEMP TABLE t3(z); + } + file_control_data_version db main +} $dv1 + +# The data version does change when SQL modifies the table +do_test dataversion1-110 { + db eval { + UPDATE t1 SET x=x+1; + } + set dv2 [file_control_data_version db] + expr {$::dv1==$dv2} +} {0} + +# But the data version is constant if there are changes to other +# schemas +set dv1 [file_control_data_version db main] +do_test dataversion1-120 { + db eval { + UPDATE t2 SET y=y+1; + } + file_control_data_version db +} $dv1 + +# Changes to the database via another connection are not detected +# until there is a read transaction. +# +sqlite3 db2 test.db +do_test dataversion1-130 { + db2 eval { + SELECT * FROM t1 + } +} {100} +do_test dataversion1-131 { + file_control_data_version db +} $dv1 +do_test dataversion1-132 { + db2 eval { + UPDATE t1 SET x=x+1; + } + set dv2 [file_control_data_version db] + expr {$::dv1==$dv2} +} {1} +do_test dataversion1-133 { + db eval {SELECT * FROM t1} + set dv2 [file_control_data_version db] + expr {$::dv1==$dv2} +} {0} + + + +finish_test diff --git a/test/dbpage.test b/test/dbpage.test new file mode 100644 index 0000000000..754bc17926 --- /dev/null +++ b/test/dbpage.test @@ -0,0 +1,104 @@ +# 2017-10-11 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the sqlite_dbpage virtual table. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix dbpage + +ifcapable !vtab||!compound { + finish_test + return +} + +do_test 100 { + execsql { + PRAGMA auto_vacuum=0; + PRAGMA page_size=4096; + PRAGMA journal_mode=WAL; + } + execsql { + CREATE TABLE t1(a,b); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b) SELECT x, printf('%d-x%.*c',x,x,'x') FROM c; + PRAGMA integrity_check; + } +} {ok} +do_execsql_test 110 { + SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage('main') ORDER BY pgno; +} {1 X'53514C6974' 2 X'0500000001' 3 X'0D0000004E' 4 X'0D00000016'} +do_execsql_test 120 { + SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=2; +} {2 X'0500000001'} +do_execsql_test 130 { + SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=4; +} {4 X'0D00000016'} +do_execsql_test 140 { + SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=5; +} {} +do_execsql_test 150 { + SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=0; +} {} +do_execsql_test 160 { + ATTACH ':memory:' AS aux1; + PRAGMA aux1.page_size=4096; + CREATE TABLE aux1.t2(a,b,c); + INSERT INTO t2 VALUES(11,12,13); + SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage('aux1'); +} {1 X'53514C6974' 2 X'0D00000001'} +do_execsql_test 170 { + CREATE TABLE aux1.x3(x,y,z); + INSERT INTO x3(x,y,z) VALUES(1,'main',1),(2,'aux1',1); + SELECT pgno, schema, substr(data,1,6) + FROM sqlite_dbpage, x3 + WHERE sqlite_dbpage.schema=x3.y AND sqlite_dbpage.pgno=x3.z + ORDER BY x3.x; +} {1 main SQLite 1 aux1 SQLite} + +do_execsql_test 200 { + CREATE TEMP TABLE saved_content(x); + INSERT INTO saved_content(x) SELECT data FROM sqlite_dbpage WHERE pgno=4; + UPDATE sqlite_dbpage SET data=zeroblob(4096) WHERE pgno=4; +} {} +do_catchsql_test 210 { + PRAGMA integrity_check; +} {1 {database disk image is malformed}} +do_execsql_test 220 { + SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage('main') ORDER BY pgno; +} {1 X'53514C6974' 2 X'0500000001' 3 X'0D0000004E' 4 X'0000000000'} +do_execsql_test 230 { + UPDATE sqlite_dbpage SET data=(SELECT x FROM saved_content) WHERE pgno=4; +} {} +do_catchsql_test 230 { + PRAGMA integrity_check; +} {0 ok} +do_execsql_test 240 { + DELETE FROM saved_content; + INSERT INTO saved_content(x) + SELECT data FROM sqlite_dbpage WHERE schema='aux1' AND pgno=2; +} {} +do_execsql_test 241 { + UPDATE sqlite_dbpage SET data=zeroblob(4096) WHERE pgno=2 AND schema='aux1'; +} {} +do_catchsql_test 250 { + PRAGMA aux1.integrity_check; +} {1 {database disk image is malformed}} +do_execsql_test 260 { + UPDATE sqlite_dbpage SET data=(SELECT x FROM saved_content) + WHERE pgno=2 AND schema='aux1'; +} {} +do_catchsql_test 270 { + PRAGMA aux1.integrity_check; +} {0 ok} + +finish_test diff --git a/test/dbstatus.test b/test/dbstatus.test index 711d66ebb3..57b91cda1a 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -415,4 +415,43 @@ ifcapable shared_cache { } } +#------------------------------------------------------------------------- +# Test that passing an out-of-range value to sqlite3_stmt_status does +# not cause a crash. +reset_db +do_execsql_test 5.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); +} + +do_test 5.1 { + set ::stmt [sqlite3_prepare db "SELECT * FROM t1" -1 dummy] + sqlite3_step $::stmt + sqlite3_step $::stmt + sqlite3_step $::stmt + sqlite3_reset $::stmt +} {SQLITE_OK} + +ifcapable api_armor { + do_test 5.2 { sqlite3_stmt_status $::stmt -1 0 } 0 +} +do_test 5.3 { sqlite3_stmt_status $::stmt 0 0 } 0 +do_test 5.4 { + expr [sqlite3_stmt_status $::stmt 99 0]>0 +} 1 +foreach {tn id res} { + 1 SQLITE_STMTSTATUS_MEMUSED 1 + 2 SQLITE_STMTSTATUS_FULLSCAN_STEP 1 + 3 SQLITE_STMTSTATUS_SORT 0 + 4 SQLITE_STMTSTATUS_AUTOINDEX 0 + 5 SQLITE_STMTSTATUS_VM_STEP 1 + 6 SQLITE_STMTSTATUS_REPREPARE 0 + 7 SQLITE_STMTSTATUS_RUN 1 +} { +if {$tn==2} breakpoint + do_test 5.5.$tn { expr [sqlite3_stmt_status $::stmt $id 0]>0 } $res +} + +sqlite3_finalize $::stmt finish_test diff --git a/test/dbstatus2.test b/test/dbstatus2.test index eff4b0207f..5e9ea888a6 100644 --- a/test/dbstatus2.test +++ b/test/dbstatus2.test @@ -37,6 +37,10 @@ proc db_write {db {reset 0}} { sqlite3_db_status $db CACHE_WRITE $reset } +proc db_spill {db {reset 0}} { + sqlite3_db_status $db CACHE_SPILL $reset +} + do_test 1.1 { db close sqlite3 db test.db @@ -98,5 +102,14 @@ do_test 2.7 { } {0 4 0} do_test 2.8 { db_write db 1 } {0 4 0} do_test 2.9 { db_write db 0 } {0 0 0} + +do_test 3.0 { db_spill db 1 } {0 0 0} +do_test 3.1 { db_spill db 0 } {0 0 0} +do_execsql_test 3.2 { + PRAGMA journal_mode=DELETE; + PRAGMA cache_size=3; + UPDATE t1 SET b=randomblob(1000); +} {delete} +do_test 3.3 { db_spill db 0 } {0 8 0} finish_test diff --git a/test/delete.test b/test/delete.test index 8e84ed4665..a448e52dd2 100644 --- a/test/delete.test +++ b/test/delete.test @@ -403,5 +403,17 @@ do_execsql_test delete-10.2 { SELECT * FROM t1 WHERE a='1' AND b='2'; } +do_execsql_test delete-11.0 { + CREATE TABLE t11(a INTEGER PRIMARY KEY, b INT); + WITH RECURSIVE cnt(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM cnt WHERE x<20) + INSERT INTO t11(a,b) SELECT x, (x*17)%100 FROM cnt; + SELECT * FROM t11; +} {1 17 2 34 3 51 4 68 5 85 6 2 7 19 8 36 9 53 10 70 11 87 12 4 13 21 14 38 15 55 16 72 17 89 18 6 19 23 20 40} +do_execsql_test delete-11.1 { + DELETE FROM t11 AS xyz + WHERE EXISTS(SELECT 1 FROM t11 WHERE t11.a>xyz.a AND t11.b<=xyz.b); + SELECT * FROM t11; +} {6 2 12 4 18 6 19 23 20 40} + finish_test diff --git a/test/delete_db.test b/test/delete_db.test index 09c44ff9f3..6edd9c242e 100644 --- a/test/delete_db.test +++ b/test/delete_db.test @@ -17,6 +17,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix delete_db +if {[atomic_batch_write test.db]} { + finish_test + return +} + proc delete_all {} { foreach f [glob -nocomplain test2*] { file delete $f } foreach f [glob -nocomplain test3*] { file delete $f } diff --git a/test/distinct2.test b/test/distinct2.test index a7d59db705..31ab355132 100644 --- a/test/distinct2.test +++ b/test/distinct2.test @@ -179,5 +179,55 @@ do_execsql_test 920 { wxYZ wxYz wxYz wxyZ wxyZ wxyz wxyz } +# Ticket https://sqlite.org/src/info/ef9318757b152e3a on 2017-11-21 +# Incorrect result due to a skip-ahead-distinct optimization on a +# join where no rows of the inner loop appear in the result set. +# +db close +sqlite3 db :memory: +do_execsql_test 1000 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); + CREATE INDEX t1b ON t1(b); + CREATE TABLE t2(x INTEGER PRIMARY KEY, y INTEGER); + CREATE INDEX t2y ON t2(y); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<49) + INSERT INTO t1(b) SELECT x/10 - 1 FROM c; + WITH RECURSIVE c(x) AS (VALUES(-1) UNION ALL SELECT x+1 FROM c WHERE x<19) + INSERT INTO t2(x,y) SELECT x, 1 FROM c; + SELECT DISTINCT y FROM t1, t2 WHERE b=x AND b<>-1; + ANALYZE; + SELECT DISTINCT y FROM t1, t2 WHERE b=x AND b<>-1; +} {1 1} +db close +sqlite3 db :memory: +do_execsql_test 1010 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); + CREATE INDEX t1b ON t1(b); + CREATE TABLE t2(x INTEGER PRIMARY KEY, y INTEGER); + CREATE INDEX t2y ON t2(y); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<49) + INSERT INTO t1(b) SELECT -(x/10 - 1) FROM c; + WITH RECURSIVE c(x) AS (VALUES(-1) UNION ALL SELECT x+1 FROM c WHERE x<19) + INSERT INTO t2(x,y) SELECT -x, 1 FROM c; + SELECT DISTINCT y FROM t1, t2 WHERE b=x AND b<>1 ORDER BY y DESC; + ANALYZE; + SELECT DISTINCT y FROM t1, t2 WHERE b=x AND b<>1 ORDER BY y DESC; +} {1 1} +db close +sqlite3 db :memory: +do_execsql_test 1020 { + CREATE TABLE t1(a, b); + CREATE INDEX t1a ON t1(a, b); + -- Lots of rows of (1, 'no'), followed by a single (1, 'yes'). + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a, b) SELECT 1, 'no' FROM c; + INSERT INTO t1(a, b) VALUES(1, 'yes'); + CREATE TABLE t2(x PRIMARY KEY); + INSERT INTO t2 VALUES('yes'); + SELECT DISTINCT a FROM t1, t2 WHERE x=b; + ANALYZE; + SELECT DISTINCT a FROM t1, t2 WHERE x=b; +} {1 1} + finish_test diff --git a/test/e_createtable.test b/test/e_createtable.test index f07fbb9c74..7f6cf48ce9 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -656,11 +656,11 @@ do_createtable_tests 2.1 -tclquery { 5 "CREATE TABLE x1 AS SELECT count(a) AS a, max(b) FROM t1" {a max(b)} } -# EVIDENCE-OF: R-37111-22855 The declared type of each column is +# EVIDENCE-OF: R-55407-45319 The declared type of each column is # determined by the expression affinity of the corresponding expression # in the result set of the SELECT statement, as follows: Expression # Affinity Column Declared Type TEXT "TEXT" NUMERIC "NUM" INTEGER "INT" -# REAL "REAL" NONE "" (empty string) +# REAL "REAL" BLOB (a.k.a "NONE") "" (empty string) # do_createtable_tests 2.2 -tclquery { table_column_decltypes x1 @@ -883,8 +883,8 @@ do_execsql_test e_createtable-3.3.1 { ); } {} -# EVIDENCE-OF: R-18415-27776 For the purposes of the DEFAULT clause, an -# expression is considered constant if it does contains no sub-queries, +# EVIDENCE-OF: R-33440-07331 For the purposes of the DEFAULT clause, an +# expression is considered constant if it contains no sub-queries, # column or table references, bound parameters, or string literals # enclosed in double-quotes instead of single-quotes. # @@ -1385,13 +1385,13 @@ do_execsql_test 4.10.0 { } do_createtable_tests 4.10 { 1 "EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 5" - {0 0 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (b=?)}} + {/*SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (b=?)*/} 2 "EXPLAIN QUERY PLAN SELECT * FROM t2 ORDER BY b, c" - {0 0 0 {SCAN TABLE t2 USING INDEX sqlite_autoindex_t2_1}} + {/*SCAN TABLE t2 USING INDEX sqlite_autoindex_t2_1*/} 3 "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE b=10 AND c>10" - {0 0 0 {SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (b=? AND c>?)}} + {/*SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (b=? AND c>?)*/} } # EVIDENCE-OF: R-45493-35653 A CHECK constraint may be attached to a diff --git a/test/e_expr.test b/test/e_expr.test index 373ffef4f9..1cac31948b 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1663,6 +1663,50 @@ do_expr_test e_expr-32.2.3 { do_expr_test e_expr-32.2.4 { CAST(9223372036854775807 AS NUMERIC) } integer 9223372036854775807 +do_expr_test e_expr-32.2.5 { + CAST('9223372036854775807 ' AS NUMERIC) +} integer 9223372036854775807 +do_expr_test e_expr-32.2.6 { + CAST(' 9223372036854775807 ' AS NUMERIC) +} integer 9223372036854775807 +do_expr_test e_expr-32.2.7 { + CAST(' ' AS NUMERIC) +} integer 0 +do_execsql_test e_expr-32.2.8 { + WITH t1(x) AS (VALUES + ('9000000000000000001'), + ('9000000000000000001x'), + ('9000000000000000001 '), + (' 9000000000000000001 '), + (' 9000000000000000001'), + (' 9000000000000000001.'), + ('9223372036854775807'), + ('9223372036854775807 '), + (' 9223372036854775807 '), + ('9223372036854775808'), + (' 9223372036854775808 '), + ('9223372036854775807.0'), + ('9223372036854775807e+0'), + ('-5.0'), + ('-5e+0')) + SELECT typeof(CAST(x AS NUMERIC)), CAST(x AS NUMERIC)||'' FROM t1; +} [list \ + integer 9000000000000000001 \ + integer 9000000000000000001 \ + integer 9000000000000000001 \ + integer 9000000000000000001 \ + integer 9000000000000000001 \ + integer 9000000000000000001 \ + integer 9223372036854775807 \ + integer 9223372036854775807 \ + integer 9223372036854775807 \ + real 9.22337203685478e+18 \ + real 9.22337203685478e+18 \ + integer 9223372036854775807 \ + integer 9223372036854775807 \ + integer -5 \ + integer -5 \ +] # EVIDENCE-OF: R-64550-29191 Note that the result from casting any # non-BLOB value into a BLOB and the result from casting any BLOB value diff --git a/test/e_fkey.test b/test/e_fkey.test index 33e7fed6de..740078c191 100644 --- a/test/e_fkey.test +++ b/test/e_fkey.test @@ -24,7 +24,24 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -proc eqp {sql {db db}} { uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db } +proc eqp {sql {db db}} { + uplevel [subst -nocommands { + set eqpres [list] + $db eval "$sql" { + lappend eqpres [set detail] + } + set eqpres + }] +} + +proc do_detail_test {tn sql res} { + set normalres [list {*}$res] + uplevel [subst -nocommands { + do_test $tn { + eqp { $sql } + } {$normalres} + }] +} ########################################################################### ### SECTION 2: Enabling Foreign Key Support @@ -970,20 +987,20 @@ do_test e_fkey-25.1 { ); } } {} -do_execsql_test e_fkey-25.2 { +do_detail_test e_fkey-25.2 { PRAGMA foreign_keys = OFF; EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1; EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?; } { - 0 0 0 {SCAN TABLE artist} - 0 0 0 {SCAN TABLE track} + {SCAN TABLE artist} + {SCAN TABLE track} } -do_execsql_test e_fkey-25.3 { +do_detail_test e_fkey-25.3 { PRAGMA foreign_keys = ON; EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1; } { - 0 0 0 {SCAN TABLE artist} - 0 0 0 {SCAN TABLE track} + {SCAN TABLE artist} + {SCAN TABLE track} } do_test e_fkey-25.4 { execsql { @@ -1097,21 +1114,20 @@ do_test e_fkey-27.1 { do_test e_fkey-27.2 { eqp { INSERT INTO artist VALUES(?, ?) } } {} -do_execsql_test e_fkey-27.3 { +do_detail_test e_fkey-27.3 { EXPLAIN QUERY PLAN UPDATE artist SET artistid = ?, artistname = ? } { - 0 0 0 {SCAN TABLE artist} - 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)} - 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)} + {SCAN TABLE artist} + {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)} + {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)} } -do_execsql_test e_fkey-27.4 { +do_detail_test e_fkey-27.4 { EXPLAIN QUERY PLAN DELETE FROM artist } { - 0 0 0 {SCAN TABLE artist} - 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)} + {SCAN TABLE artist} + {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)} } - ########################################################################### ### SECTION 4.1: Composite Foreign Key Constraints ########################################################################### diff --git a/test/e_select.test b/test/e_select.test index 9aa2de6038..5916e94826 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -748,7 +748,7 @@ do_execsql_test e_select-3.2.1a { SELECT k FROM x1 LEFT JOIN x2 USING(k) } {1 2 3 4 5 6} do_execsql_test e_select-3.2.1b { - SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k + SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k ORDER BY +k } {1 3 5} do_execsql_test e_select-3.2.2 { SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k IS NULL @@ -801,7 +801,7 @@ do_select_tests e_select-4.1 { 4 "SELECT z2.* FROM z1,z2 LIMIT 1" {{} 21} 5 "SELECT z2.*, z1.* FROM z1,z2 LIMIT 1" {{} 21 51.65 -59.58 belfries} - 6 "SELECT count(*), * FROM z1" {6 63 born -26} + 6 "SELECT count(*), * FROM z1" {6 51.65 -59.58 belfries} 7 "SELECT max(a), * FROM z1" {63 63 born -26} 8 "SELECT *, min(a) FROM z1" {-5 {} 75 -5} @@ -939,13 +939,13 @@ do_execsql_test e_select-4.6.0 { INSERT INTO a2 VALUES(10, 4); } {} do_select_tests e_select-4.6 { - 1 "SELECT one, two, count(*) FROM a1" {4 10 4} - 2 "SELECT one, two, count(*) FROM a1 WHERE one<3" {2 3 2} + 1 "SELECT one, two, count(*) FROM a1" {1 1 4} + 2 "SELECT one, two, count(*) FROM a1 WHERE one<3" {1 1 2} 3 "SELECT one, two, count(*) FROM a1 WHERE one>3" {4 10 1} - 4 "SELECT *, count(*) FROM a1 JOIN a2" {4 10 10 4 16} - 5 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {3 6 2 3} - 6 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {3 6 2 3} - 7 "SELECT group_concat(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 3 6} + 4 "SELECT *, count(*) FROM a1 JOIN a2" {1 1 1 1 16} + 5 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} + 6 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} + 7 "SELECT group_concat(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 1 1} } # EVIDENCE-OF: R-04486-07266 Or, if the dataset contains zero rows, then @@ -1128,7 +1128,7 @@ do_select_tests e_select-4.13 { 2.1 "SELECT up FROM c1 GROUP BY up HAVING down>10" {y} 2.2 "SELECT up FROM c1 GROUP BY up HAVING up='y'" {y} - 2.3 "SELECT i, j FROM c2 GROUP BY i>4 HAVING i>6" {9 36} + 2.3 "SELECT i, j FROM c2 GROUP BY i>4 HAVING j>6" {5 10} } # EVIDENCE-OF: R-23927-54081 Each expression in the result-set is then @@ -1154,12 +1154,12 @@ do_select_tests e_select-4.15 { # for the same row. # do_select_tests e_select-4.15 { - 1 "SELECT i, j FROM c2 GROUP BY i%2" {8 28 9 36} - 2 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j<30" {8 28} - 3 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {9 36} - 4 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {9 36} + 1 "SELECT i, j FROM c2 GROUP BY i%2" {2 1 1 0} + 2 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j<30" {2 1 1 0} + 3 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {} + 4 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {} 5 "SELECT count(*), i, k FROM c2 NATURAL JOIN c3 GROUP BY substr(k, 1, 1)" - {2 5 boron 2 2 helium 1 3 lithium} + {2 4 beryllium 2 1 hydrogen 1 3 lithium} } # EVIDENCE-OF: R-19334-12811 Each group of input dataset rows diff --git a/test/e_uri.test b/test/e_uri.test index 95b53f1d6b..dbcc6f3e0b 100644 --- a/test/e_uri.test +++ b/test/e_uri.test @@ -50,8 +50,8 @@ proc open_uri_error {uri} { # and the filename argument begins with "file:", then the filename is # interpreted as a URI. # -# EVIDENCE-OF: R-24124-56960 URI filename interpretation is enabled if -# the SQLITE_OPEN_URI flag is set in the fourth argument to +# EVIDENCE-OF: R-27632-24205 URI filename interpretation is enabled if +# the SQLITE_OPEN_URI flag is set in the third argument to # sqlite3_open_v2(), or if it has been enabled globally using the # SQLITE_CONFIG_URI option with the sqlite3_config() method or by the # SQLITE_USE_URI compile-time option. diff --git a/test/eqp.test b/test/eqp.test index 30fcdf287f..3de746e3a0 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -43,78 +43,110 @@ do_execsql_test 1.1 { do_eqp_test 1.2 { SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2; } { - 0 0 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)} - 0 0 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)} - 0 1 0 {SCAN TABLE t2} + QUERY PLAN + |--MULTI-INDEX OR + | |--SEARCH TABLE t1 USING INDEX i1 (a=?) + | `--SEARCH TABLE t1 USING INDEX i2 (b=?) + `--SCAN TABLE t2 } do_eqp_test 1.3 { SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2; } { - 0 0 0 {SCAN TABLE t2} - 0 1 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)} - 0 1 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)} + QUERY PLAN + |--SCAN TABLE t2 + `--MULTI-INDEX OR + |--SEARCH TABLE t1 USING INDEX i1 (a=?) + `--SEARCH TABLE t1 USING INDEX i2 (b=?) } do_eqp_test 1.3 { SELECT a FROM t1 ORDER BY a } { - 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1} + QUERY PLAN + `--SCAN TABLE t1 USING COVERING INDEX i1 } do_eqp_test 1.4 { SELECT a FROM t1 ORDER BY +a } { - 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE t1 USING COVERING INDEX i1 + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 1.5 { SELECT a FROM t1 WHERE a=4 } { - 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)} + QUERY PLAN + `--SEARCH TABLE t1 USING COVERING INDEX i1 (a=?) } do_eqp_test 1.6 { SELECT DISTINCT count(*) FROM t3 GROUP BY a; } { - 0 0 0 {SCAN TABLE t3} - 0 0 0 {USE TEMP B-TREE FOR GROUP BY} - 0 0 0 {USE TEMP B-TREE FOR DISTINCT} + QUERY PLAN + |--SCAN TABLE t3 + |--USE TEMP B-TREE FOR GROUP BY + `--USE TEMP B-TREE FOR DISTINCT } do_eqp_test 1.7 { SELECT * FROM t3 JOIN (SELECT 1) } { - 0 0 1 {SCAN SUBQUERY 1} - 0 1 0 {SCAN TABLE t3} + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--SCAN CONSTANT ROW + |--SCAN SUBQUERY xxxxxx + `--SCAN TABLE t3 } do_eqp_test 1.8 { SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2) } { - 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)} - 0 0 1 {SCAN SUBQUERY 1} - 0 1 0 {SCAN TABLE t3} + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--COMPOUND QUERY + | |--LEFT-MOST SUBQUERY + | | `--SCAN CONSTANT ROW + | `--UNION USING TEMP B-TREE + | `--SCAN CONSTANT ROW + |--SCAN SUBQUERY xxxxxx + `--SCAN TABLE t3 } do_eqp_test 1.9 { SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17) } { - 3 0 0 {SCAN TABLE t3} - 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)} - 0 0 1 {SCAN SUBQUERY 1} - 0 1 0 {SCAN TABLE t3} + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--COMPOUND QUERY + | |--LEFT-MOST SUBQUERY + | | `--SCAN CONSTANT ROW + | `--EXCEPT USING TEMP B-TREE + | `--SCAN TABLE t3 + |--SCAN SUBQUERY xxxxxx + `--SCAN TABLE t3 } do_eqp_test 1.10 { SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17) } { - 3 0 0 {SCAN TABLE t3} - 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (INTERSECT)} - 0 0 1 {SCAN SUBQUERY 1} - 0 1 0 {SCAN TABLE t3} + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--COMPOUND QUERY + | |--LEFT-MOST SUBQUERY + | | `--SCAN CONSTANT ROW + | `--INTERSECT USING TEMP B-TREE + | `--SCAN TABLE t3 + |--SCAN SUBQUERY xxxxxx + `--SCAN TABLE t3 } do_eqp_test 1.11 { SELECT * FROM t3 JOIN (SELECT 1 UNION ALL SELECT a FROM t3 LIMIT 17) } { - 3 0 0 {SCAN TABLE t3} - 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)} - 0 0 1 {SCAN SUBQUERY 1} - 0 1 0 {SCAN TABLE t3} + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--COMPOUND QUERY + | |--LEFT-MOST SUBQUERY + | | `--SCAN CONSTANT ROW + | `--UNION ALL + | `--SCAN TABLE t3 + |--SCAN SUBQUERY xxxxxx + `--SCAN TABLE t3 } #------------------------------------------------------------------------- @@ -129,48 +161,58 @@ do_execsql_test 2.1 { } det 2.2.1 "SELECT DISTINCT min(x), max(x) FROM t1 GROUP BY x ORDER BY 1" { - 0 0 0 {SCAN TABLE t1} - 0 0 0 {USE TEMP B-TREE FOR GROUP BY} - 0 0 0 {USE TEMP B-TREE FOR DISTINCT} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE t1 + |--USE TEMP B-TREE FOR GROUP BY + |--USE TEMP B-TREE FOR DISTINCT + `--USE TEMP B-TREE FOR ORDER BY } det 2.2.2 "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORDER BY 1" { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} - 0 0 0 {USE TEMP B-TREE FOR DISTINCT} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE t2 USING COVERING INDEX t2i1 + |--USE TEMP B-TREE FOR DISTINCT + `--USE TEMP B-TREE FOR ORDER BY } det 2.2.3 "SELECT DISTINCT * FROM t1" { - 0 0 0 {SCAN TABLE t1} - 0 0 0 {USE TEMP B-TREE FOR DISTINCT} + QUERY PLAN + |--SCAN TABLE t1 + `--USE TEMP B-TREE FOR DISTINCT } det 2.2.4 "SELECT DISTINCT * FROM t1, t2" { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE t2} - 0 0 0 {USE TEMP B-TREE FOR DISTINCT} + QUERY PLAN + |--SCAN TABLE t1 + |--SCAN TABLE t2 + `--USE TEMP B-TREE FOR DISTINCT } det 2.2.5 "SELECT DISTINCT * FROM t1, t2 ORDER BY t1.x" { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SCAN TABLE t2} - 0 0 0 {USE TEMP B-TREE FOR DISTINCT} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SCAN TABLE t1 + |--SCAN TABLE t2 + |--USE TEMP B-TREE FOR DISTINCT + `--USE TEMP B-TREE FOR ORDER BY } det 2.2.6 "SELECT DISTINCT t2.x FROM t1, t2 ORDER BY t2.x" { - 0 0 1 {SCAN TABLE t2 USING COVERING INDEX t2i1} - 0 1 0 {SCAN TABLE t1} + QUERY PLAN + |--SCAN TABLE t2 USING COVERING INDEX t2i1 + `--SCAN TABLE t1 } det 2.3.1 "SELECT max(x) FROM t2" { - 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1} + QUERY PLAN + `--SEARCH TABLE t2 USING COVERING INDEX t2i1 } det 2.3.2 "SELECT min(x) FROM t2" { - 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1} + QUERY PLAN + `--SEARCH TABLE t2 USING COVERING INDEX t2i1 } det 2.3.3 "SELECT min(x), max(x) FROM t2" { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} + QUERY PLAN + `--SCAN TABLE t2 USING COVERING INDEX t2i1 } det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" { - 0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + `--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) } @@ -181,40 +223,46 @@ det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" { do_eqp_test 3.1.1 { SELECT (SELECT x FROM t1 AS sub) FROM t1; } { - 0 0 0 {SCAN TABLE t1} - 0 0 0 {EXECUTE SCALAR SUBQUERY 1} - 1 0 0 {SCAN TABLE t1 AS sub} + QUERY PLAN + |--SCAN TABLE t1 + `--SCALAR SUBQUERY + `--SCAN TABLE t1 AS sub } do_eqp_test 3.1.2 { SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub); } { - 0 0 0 {EXECUTE SCALAR SUBQUERY 1} - 1 0 0 {SCAN TABLE t1 AS sub} - 0 0 0 {SCAN TABLE t1} + QUERY PLAN + |--SCAN TABLE t1 + `--SCALAR SUBQUERY + `--SCAN TABLE t1 AS sub } do_eqp_test 3.1.3 { SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y); } { - 0 0 0 {EXECUTE SCALAR SUBQUERY 1} - 1 0 0 {SCAN TABLE t1 AS sub} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 0 0 0 {SCAN TABLE t1} + QUERY PLAN + |--SCAN TABLE t1 + `--SCALAR SUBQUERY + |--SCAN TABLE t1 AS sub + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 3.1.4 { SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x); } { - 0 0 0 {EXECUTE SCALAR SUBQUERY 1} - 1 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} - 0 0 0 {SCAN TABLE t1} + QUERY PLAN + |--SCAN TABLE t1 + `--SCALAR SUBQUERY + `--SCAN TABLE t2 USING COVERING INDEX t2i1 } det 3.2.1 { SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 0 0 0 {SCAN SUBQUERY 1} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--CO-ROUTINE xxxxxx + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + |--SCAN SUBQUERY xxxxxx + `--USE TEMP B-TREE FOR ORDER BY } det 3.2.2 { SELECT * FROM @@ -222,34 +270,40 @@ det 3.2.2 { (SELECT * FROM t2 ORDER BY x LIMIT 10) AS x2 ORDER BY x2.y LIMIT 5 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2 USING INDEX t2i1} - 0 0 0 {SCAN SUBQUERY 1 AS x1} - 0 1 1 {SCAN SUBQUERY 2 AS x2} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + |--MATERIALIZE xxxxxx + | `--SCAN TABLE t2 USING INDEX t2i1 + |--SCAN SUBQUERY xxxxxx AS x1 + |--SCAN SUBQUERY xxxxxx AS x2 + `--USE TEMP B-TREE FOR ORDER BY } det 3.3.1 { SELECT * FROM t1 WHERE y IN (SELECT y FROM t2) } { - 0 0 0 {SCAN TABLE t1} - 0 0 0 {EXECUTE LIST SUBQUERY 1} - 1 0 0 {SCAN TABLE t2} + QUERY PLAN + |--SCAN TABLE t1 + `--LIST SUBQUERY + `--SCAN TABLE t2 } det 3.3.2 { SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x) } { - 0 0 0 {SCAN TABLE t1} - 0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} - 1 0 0 {SCAN TABLE t2} + QUERY PLAN + |--SCAN TABLE t1 + `--CORRELATED LIST SUBQUERY + `--SCAN TABLE t2 } det 3.3.3 { SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x) } { - 0 0 0 {SCAN TABLE t1} - 0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 1} - 1 0 0 {SCAN TABLE t2} + QUERY PLAN + |--SCAN TABLE t1 + `--CORRELATED SCALAR SUBQUERY + `--SCAN TABLE t2 } #------------------------------------------------------------------------- @@ -258,119 +312,158 @@ det 3.3.3 { do_eqp_test 4.1.1 { SELECT * FROM t1 UNION ALL SELECT * FROM t2 } { - 1 0 0 {SCAN TABLE t1} - 2 0 0 {SCAN TABLE t2} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | `--SCAN TABLE t1 + `--UNION ALL + `--SCAN TABLE t2 } do_eqp_test 4.1.2 { SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 2 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2} - 2 0 0 {USE TEMP B-TREE FOR ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} + QUERY PLAN + `--MERGE (UNION ALL) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + |--SCAN TABLE t2 + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 4.1.3 { SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 2 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2} - 2 0 0 {USE TEMP B-TREE FOR ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)} + QUERY PLAN + `--MERGE (UNION) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + |--SCAN TABLE t2 + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 4.1.4 { SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 2 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2} - 2 0 0 {USE TEMP B-TREE FOR ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)} + QUERY PLAN + `--MERGE (INTERSECT) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + |--SCAN TABLE t2 + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 4.1.5 { SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 2 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2} - 2 0 0 {USE TEMP B-TREE FOR ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} + QUERY PLAN + `--MERGE (EXCEPT) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + |--SCAN TABLE t2 + `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 4.2.2 { SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 1 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2 USING INDEX t2i1} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} + QUERY PLAN + `--MERGE (UNION ALL) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + `--SCAN TABLE t2 USING INDEX t2i1 } do_eqp_test 4.2.3 { SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 1 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2 USING INDEX t2i1} - 2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)} + QUERY PLAN + `--MERGE (UNION) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + |--SCAN TABLE t2 USING INDEX t2i1 + `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY } do_eqp_test 4.2.4 { SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 1 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2 USING INDEX t2i1} - 2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)} + QUERY PLAN + `--MERGE (INTERSECT) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + |--SCAN TABLE t2 USING INDEX t2i1 + `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY } do_eqp_test 4.2.5 { SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 1 } { - 1 0 0 {SCAN TABLE t1} - 1 0 0 {USE TEMP B-TREE FOR ORDER BY} - 2 0 0 {SCAN TABLE t2 USING INDEX t2i1} - 2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} + QUERY PLAN + `--MERGE (EXCEPT) + |--LEFT + | |--SCAN TABLE t1 + | `--USE TEMP B-TREE FOR ORDER BY + `--RIGHT + |--SCAN TABLE t2 USING INDEX t2i1 + `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY } do_eqp_test 4.3.1 { SELECT x FROM t1 UNION SELECT x FROM t2 } { - 1 0 0 {SCAN TABLE t1} - 2 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | `--SCAN TABLE t1 + `--UNION USING TEMP B-TREE + `--SCAN TABLE t2 USING COVERING INDEX t2i1 } do_eqp_test 4.3.2 { SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 } { - 2 0 0 {SCAN TABLE t1} - 3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} - 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)} - 4 0 0 {SCAN TABLE t1} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)} + QUERY PLAN + `--COMPOUND QUERY + |--LEFT-MOST SUBQUERY + | `--SCAN TABLE t1 + |--UNION USING TEMP B-TREE + | `--SCAN TABLE t2 USING COVERING INDEX t2i1 + `--UNION USING TEMP B-TREE + `--SCAN TABLE t1 } do_eqp_test 4.3.3 { SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ORDER BY 1 } { - 2 0 0 {SCAN TABLE t1} - 2 0 0 {USE TEMP B-TREE FOR ORDER BY} - 3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} - 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION)} - 4 0 0 {SCAN TABLE t1} - 4 0 0 {USE TEMP B-TREE FOR ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 4 (UNION)} + QUERY PLAN + `--MERGE (UNION) + |--LEFT + | `--MERGE (UNION) + | |--LEFT + | | |--SCAN TABLE t1 + | | `--USE TEMP B-TREE FOR ORDER BY + | `--RIGHT + | `--SCAN TABLE t2 USING COVERING INDEX t2i1 + `--RIGHT + |--SCAN TABLE t1 + `--USE TEMP B-TREE FOR ORDER BY } +if 0 { #------------------------------------------------------------------------- # This next block of tests verifies that the examples on the # lang_explain.html page are correct. # drop_all_tables -# EVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b +# XVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b # FROM t1 WHERE a=1; # 0|0|0|SCAN TABLE t1 # @@ -379,7 +472,7 @@ det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" { 0 0 0 {SCAN TABLE t1} } -# EVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a); +# XVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a); # sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; # 0|0|0|SEARCH TABLE t1 USING INDEX i1 # @@ -388,7 +481,7 @@ det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" { 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)} } -# EVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b); +# XVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b); # sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) # @@ -397,7 +490,7 @@ det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" { 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)} } -# EVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN +# XVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN # SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2; # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?) # 0|1|1|SCAN TABLE t2 @@ -408,7 +501,7 @@ det 5.4.1 "SELECT t1.a, t2.c FROM t1, t2 WHERE t1.a=1 AND t1.b>2" { 0 1 1 {SCAN TABLE t2} } -# EVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN +# XVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN # SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2; # 0|0|1|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?) # 0|1|0|SCAN TABLE t2 @@ -418,7 +511,7 @@ det 5.5 "SELECT t1.a, t2.c FROM t2, t1 WHERE t1.a=1 AND t1.b>2" { 0 1 0 {SCAN TABLE t2} } -# EVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b); +# XVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b); # sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2; # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) # 0|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?) @@ -429,7 +522,7 @@ det 5.6.1 "SELECT a, b FROM t1 WHERE a=1 OR b=2" { 0 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)} } -# EVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN +# XVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN # SELECT c, d FROM t2 ORDER BY c; # 0|0|0|SCAN TABLE t2 # 0|0|0|USE TEMP B-TREE FOR ORDER BY @@ -439,7 +532,7 @@ det 5.7 "SELECT c, d FROM t2 ORDER BY c" { 0 0 0 {USE TEMP B-TREE FOR ORDER BY} } -# EVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c); +# XVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c); # sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c; # 0|0|0|SCAN TABLE t2 USING INDEX i4 # @@ -448,7 +541,7 @@ det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" { 0 0 0 {SCAN TABLE t2 USING INDEX i4} } -# EVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT +# XVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT # (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2; # 0|0|0|SCAN TABLE t2 # 0|0|0|EXECUTE SCALAR SUBQUERY 1 @@ -466,7 +559,7 @@ det 5.9 { 2 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)} } -# EVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN +# XVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN # SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x; # 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2 # 0|0|0|SCAN SUBQUERY 1 @@ -480,7 +573,7 @@ det 5.10 { 0 0 0 {USE TEMP B-TREE FOR GROUP BY} } -# EVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN +# XVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN # SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1; # 0|0|0|SEARCH TABLE t2 USING INDEX i4 (c=?) # 0|1|1|SCAN TABLE t1 @@ -490,7 +583,7 @@ det 5.11 "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1" { 0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2} } -# EVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN +# XVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN # SELECT a FROM t1 UNION SELECT c FROM t2; # 1|0|0|SCAN TABLE t1 # 2|0|0|SCAN TABLE t2 @@ -502,7 +595,7 @@ det 5.12 "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2" { 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} } -# EVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN +# XVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN # SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1; # 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2 # 2|0|0|SCAN TABLE t2 2|0|0|USE TEMP B-TREE FOR ORDER BY @@ -515,7 +608,6 @@ det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" { 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} } - if {![nonzero_reserved_bytes]} { #------------------------------------------------------------------------- # The following tests - eqp-6.* - test that the example C code on @@ -557,6 +649,7 @@ if {![nonzero_reserved_bytes]} { 0 0 0 COMPOUND SUBQUERIES 1 AND 2 (EXCEPT) }] } +} #------------------------------------------------------------------------- # The following tests - eqp-7.* - test that queries that use the OP_Count @@ -571,11 +664,13 @@ do_execsql_test 7.0 { } det 7.1 "SELECT count(*) FROM t1" { - 0 0 0 {SCAN TABLE t1} + QUERY PLAN + `--SCAN TABLE t1 } det 7.2 "SELECT count(*) FROM t2" { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1} + QUERY PLAN + `--SCAN TABLE t2 USING COVERING INDEX i1 } do_execsql_test 7.3 { @@ -593,11 +688,13 @@ db close sqlite3 db test.db det 7.4 "SELECT count(*) FROM t1" { - 0 0 0 {SCAN TABLE t1} + QUERY PLAN + `--SCAN TABLE t1 } det 7.5 "SELECT count(*) FROM t2" { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1} + QUERY PLAN + `--SCAN TABLE t2 USING COVERING INDEX i1 } #------------------------------------------------------------------------- @@ -612,37 +709,118 @@ do_execsql_test 8.0 { } det 8.1.1 "SELECT * FROM t2" { - 0 0 0 {SCAN TABLE t2} + QUERY PLAN + `--SCAN TABLE t2 } det 8.1.2 "SELECT * FROM t2 WHERE rowid=?" { - 0 0 0 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) } det 8.1.3 "SELECT count(*) FROM t2" { - 0 0 0 {SCAN TABLE t2} + QUERY PLAN + `--SCAN TABLE t2 } det 8.2.1 "SELECT * FROM t1" { - 0 0 0 {SCAN TABLE t1} + QUERY PLAN + `--SCAN TABLE t1 } det 8.2.2 "SELECT * FROM t1 WHERE b=?" { - 0 0 0 {SEARCH TABLE t1 USING PRIMARY KEY (b=?)} + QUERY PLAN + `--SEARCH TABLE t1 USING PRIMARY KEY (b=?) } det 8.2.3 "SELECT * FROM t1 WHERE b=? AND c=?" { - 0 0 0 {SEARCH TABLE t1 USING PRIMARY KEY (b=? AND c=?)} + QUERY PLAN + `--SEARCH TABLE t1 USING PRIMARY KEY (b=? AND c=?) } det 8.2.4 "SELECT count(*) FROM t1" { - 0 0 0 {SCAN TABLE t1} + QUERY PLAN + `--SCAN TABLE t1 } - - - - - +# 2018-08-16: While working on Fossil I discovered that EXPLAIN QUERY PLAN +# did not describe IN operators implemented using a ROWID lookup. These +# test cases ensure that problem as been fixed. +# +do_execsql_test 9.0 { + -- Schema from Fossil 2018-08-16 + CREATE TABLE forumpost( + fpid INTEGER PRIMARY KEY, + froot INT, + fprev INT, + firt INT, + fmtime REAL + ); + CREATE INDEX forumthread ON forumpost(froot,fmtime); + CREATE TABLE blob( + rid INTEGER PRIMARY KEY, + rcvid INTEGER, + size INTEGER, + uuid TEXT UNIQUE NOT NULL, + content BLOB, + CHECK( length(uuid)>=40 AND rid>0 ) + ); + CREATE TABLE event( + type TEXT, + mtime DATETIME, + objid INTEGER PRIMARY KEY, + tagid INTEGER, + uid INTEGER REFERENCES user, + bgcolor TEXT, + euser TEXT, + user TEXT, + ecomment TEXT, + comment TEXT, + brief TEXT, + omtime DATETIME + ); + CREATE INDEX event_i1 ON event(mtime); + CREATE TABLE private(rid INTEGER PRIMARY KEY); +} +do_eqp_test 9.1 { + WITH thread(age,duration,cnt,root,last) AS ( + SELECT + julianday('now') - max(fmtime) AS age, + max(fmtime) - min(fmtime) AS duration, + sum(fprev IS NULL) AS msg_count, + froot, + (SELECT fpid FROM forumpost + WHERE froot=x.froot + AND fpid NOT IN private + ORDER BY fmtime DESC LIMIT 1) + FROM forumpost AS x + WHERE fpid NOT IN private --- Ensure this table mentioned in EQP output! + GROUP BY froot + ORDER BY 1 LIMIT 26 OFFSET 5 + ) + SELECT + thread.age, + thread.duration, + thread.cnt, + blob.uuid, + substr(event.comment,instr(event.comment,':')+1) + FROM thread, blob, event + WHERE blob.rid=thread.last + AND event.objid=thread.last + ORDER BY 1; +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--SCAN TABLE forumpost AS x USING INDEX forumthread + | |--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR + | |--CORRELATED SCALAR SUBQUERY + | | |--SEARCH TABLE forumpost USING COVERING INDEX forumthread (froot=?) + | | `--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR + | `--USE TEMP B-TREE FOR ORDER BY + |--SCAN SUBQUERY xxxxxx + |--SEARCH TABLE blob USING INTEGER PRIMARY KEY (rowid=?) + |--SEARCH TABLE event USING INTEGER PRIMARY KEY (rowid=?) + `--USE TEMP B-TREE FOR ORDER BY +} finish_test diff --git a/test/exclusive.test b/test/exclusive.test index 45f9318205..04de529137 100644 --- a/test/exclusive.test +++ b/test/exclusive.test @@ -252,7 +252,9 @@ db2 close # opens the journal file for exclusive access, preventing its contents # from being inspected externally. # -if {$tcl_platform(platform) != "windows"} { +if {$tcl_platform(platform) != "windows" + && [atomic_batch_write test.db]==0 +} { # Return a list of two booleans (either 0 or 1). The first is true # if the named file exists. The second is true only if the file @@ -391,6 +393,7 @@ do_test exclusive-4.5 { # Tests exclusive-5.X - test that statement journals are truncated # instead of deleted when in exclusive access mode. # +if {[atomic_batch_write test.db]==0} { # Close and reopen the database so that the temp database is no # longer active. @@ -508,4 +511,6 @@ do_execsql_test exclusive-6.5 { SELECT * FROM sqlite_master; } {exclusive} +} ;# atomic_batch_write==0 + finish_test diff --git a/test/expr.test b/test/expr.test index 7a6d477259..3cdc9180e8 100644 --- a/test/expr.test +++ b/test/expr.test @@ -977,6 +977,63 @@ do_execsql_test expr-13.9 { SELECT '' <= ""; } {1} +# 2018-02-26. Ticket https://www.sqlite.org/src/tktview/36fae083b450e3af85 +# +do_execsql_test expr-14.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(0),(1),(NULL),(0.5),('1x'),('0x'); + SELECT count(*) FROM t1 + WHERE (x OR (8==9)) != (CASE WHEN x THEN 1 ELSE 0 END); +} {0} +do_execsql_test expr-14.2 { + SELECT count(*) FROM t1 + WHERE (x OR (8==9)) != (NOT NOT x); +} {0} +do_execsql_test expr-14.3 { + SELECT sum(NOT x) FROM t1 + WHERE x +} {0} +do_execsql_test expr-14.4 { + SELECT sum(CASE WHEN x THEN 0 ELSE 1 END) FROM t1 + WHERE x +} {0} +foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] { + do_execsql_test expr-15.$tn.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(0),(1),(NULL),(0.5),('1x'),('0x'); + } + + do_test expr-15.$tn.2 { + set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL] + sqlite3_bind_double $::STMT 1 $val + sqlite3_step $::STMT + sqlite3_reset $::STMT + sqlite3_finalize $::STMT + } {SQLITE_OK} + + do_execsql_test expr-15.$tn.3 { + SELECT count(*) FROM t1 + WHERE (x OR (8==9)) != (CASE WHEN x THEN 1 ELSE 0 END); + } {0} + + do_execsql_test expr-15.$tn.4 { + SELECT count(*) FROM t1 + WHERE (x OR (8==9)) != (NOT NOT x); + } {0} + + do_execsql_test expr-15.$tn.5 { + SELECT sum(NOT x) FROM t1 + WHERE x + } {0} + + do_execsql_test expr-15.$tn.6 { + SELECT sum(CASE WHEN x THEN 0 ELSE 1 END) FROM t1 + WHERE x + } {0} +} + finish_test diff --git a/test/fallocate.test b/test/fallocate.test index 63d88ea885..0c971c08c1 100644 --- a/test/fallocate.test +++ b/test/fallocate.test @@ -61,6 +61,7 @@ do_test fallocate-1.7 { execsql { BEGIN; INSERT INTO t1 VALUES(1, 2); } if {[permutation] != "inmemory_journal" && [permutation] != "atomic-batch-write" + && [atomic_batch_write test.db]==0 } { hexio_get_int [hexio_read test.db-journal 16 4] } else { diff --git a/test/fkey1.test b/test/fkey1.test index d9b038a022..fa87335888 100644 --- a/test/fkey1.test +++ b/test/fkey1.test @@ -171,6 +171,22 @@ do_catchsql_test fkey1-5.2 { INSERT OR REPLACE INTO t11 VALUES (2, 3); } {1 {FOREIGN KEY constraint failed}} +# Make sure sqlite3_trace() output works with triggers used to implement +# FK constraints +# +ifcapable trace { + proc sqltrace {txt} { + global traceoutput + lappend traceoutput $txt + } + do_test fkey1-5.2.1 { + unset -nocomplain traceoutput + db trace sqltrace + catch {db eval {INSERT OR REPLACE INTO t11 VALUES(2,3);}} + set traceoutput + } {{INSERT OR REPLACE INTO t11 VALUES(2,3);} {INSERT OR REPLACE INTO t11 VALUES(2,3);} {INSERT OR REPLACE INTO t11 VALUES(2,3);}} +} + # A similar test to the above. do_execsql_test fkey1-5.3 { CREATE TABLE Foo ( diff --git a/test/fkey2.test b/test/fkey2.test index c2ae3788f5..0612dae74f 100644 --- a/test/fkey2.test +++ b/test/fkey2.test @@ -983,7 +983,9 @@ ifcapable altertable { # Test the sqlite_rename_parent() function directly. # proc test_rename_parent {zCreate zOld zNew} { - db eval {SELECT sqlite_rename_parent($zCreate, $zOld, $zNew)} + db eval {SELECT sqlite_rename_table( + 'main', 'table', 't1', $zCreate, $zOld, $zNew, 0 + )} } do_test fkey2-14.2.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 diff --git a/test/fkey7.test b/test/fkey7.test index 6c646a9a7f..e86fc5c57b 100644 --- a/test/fkey7.test +++ b/test/fkey7.test @@ -68,4 +68,18 @@ ifcapable incrblob { } {SQLITE_CONSTRAINT} } +ifcapable stat4 { + do_execsql_test 3.0 { + CREATE TABLE p4 (id INTEGER NOT NULL PRIMARY KEY); + INSERT INTO p4 VALUES(1), (2), (3); + + CREATE TABLE c4(x INTEGER REFERENCES p4(id) DEFERRABLE INITIALLY DEFERRED); + CREATE INDEX c4_x ON c4(x); + INSERT INTO c4 VALUES(1), (2), (3); + + ANALYZE; + INSERT INTO p4(id) VALUES(4); + } +} + finish_test diff --git a/test/fts3aa.test b/test/fts3aa.test index 10ec273cbf..d5f96d81a7 100644 --- a/test/fts3aa.test +++ b/test/fts3aa.test @@ -250,4 +250,5 @@ do_execsql_test 9.2 { CREATE VIRTUAL TABLE t10 USING fts3(<, b, c); } +expand_all_sql db finish_test diff --git a/test/fts3ao.test b/test/fts3ao.test index 2cff1350eb..d9b2233bfb 100644 --- a/test/fts3ao.test +++ b/test/fts3ao.test @@ -93,7 +93,7 @@ do_test fts3ao-2.9 { } } {1 {SQL logic error}} do_test fts3ao-2.10 { - execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } + execsql { SELECT rowid, snippet( fts_t1 ) FROM fts_t1 WHERE a MATCH 'four'; } } {1 {one three four}} do_test fts3ao-2.11 { execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} diff --git a/test/fts3aux1.test b/test/fts3aux1.test index 9bbed53c45..c7e1ac1a5c 100644 --- a/test/fts3aux1.test +++ b/test/fts3aux1.test @@ -105,10 +105,10 @@ db func rec rec # do_execsql_test 2.1.1.1 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term='braid' -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:} } +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 1:*/} do_execsql_test 2.1.1.2 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term='braid' -} {0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}} +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/} # Now show that using "term='braid'" means the virtual table returns # only 1 row to SQLite, but "+term='braid'" means all 19 are returned. @@ -154,24 +154,24 @@ do_execsql_test 2.1.5 { SELECT * FROM terms WHERE term=NULL } {} do_execsql_test 2.2.1.1 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term>'brain' -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 2:} } +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 2:*/} do_execsql_test 2.2.1.2 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term>'brain' -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} } +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/} do_execsql_test 2.2.1.3 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term<'brain' -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 4:} } +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 4:*/} do_execsql_test 2.2.1.4 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term<'brain' -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} } +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/} do_execsql_test 2.2.1.5 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term BETWEEN 'brags' AND 'brain' -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 6:} } +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 6:*/} do_execsql_test 2.2.1.6 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term BETWEEN 'brags' AND 'brain' -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} } +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/} do_test 2.2.2.1 { set cnt 0 @@ -335,8 +335,9 @@ foreach {tn sort orderby} { 9 1 "ORDER BY occurrences DESC" } { - set res [list 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}] - if {$sort} { lappend res 0 0 0 {USE TEMP B-TREE FOR ORDER BY} } + set res {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} + if {$sort} { append res {*USE TEMP B-TREE FOR ORDER BY} } + set res "/*$res*/" set sql "SELECT * FROM terms $orderby" do_execsql_test 2.3.1.$tn "EXPLAIN QUERY PLAN $sql" $res @@ -403,39 +404,48 @@ do_execsql_test 4.1 { INSERT INTO x3 SELECT term FROM terms WHERE col = '*'; } -proc do_plansql_test {tn sql r} { - uplevel do_execsql_test $tn [list "EXPLAIN QUERY PLAN $sql ; $sql"] [list $r] +proc do_plansql_test {tn sql r1 r2} { + do_eqp_test $tn.eqp $sql $r1 + do_execsql_test $tn $sql $r2 } do_plansql_test 4.2 { SELECT y FROM x2, terms WHERE y = term AND col = '*' } { - 0 0 0 {SCAN TABLE x2} - 0 1 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:} + QUERY PLAN + |--SCAN TABLE x2 + `--SCAN TABLE terms VIRTUAL TABLE INDEX 1: +} { a b c d e f g h i j k l } do_plansql_test 4.3 { SELECT y FROM terms, x2 WHERE y = term AND col = '*' } { - 0 0 1 {SCAN TABLE x2} - 0 1 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:} + QUERY PLAN + |--SCAN TABLE x2 + `--SCAN TABLE terms VIRTUAL TABLE INDEX 1: +} { a b c d e f g h i j k l } do_plansql_test 4.4 { SELECT y FROM x3, terms WHERE y = term AND col = '*' } { - 0 0 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} - 0 1 0 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)} + QUERY PLAN + |--SCAN TABLE terms VIRTUAL TABLE INDEX 0: + `--SEARCH TABLE x3 USING COVERING INDEX i1 (y=?) +} { a b c d e f g h i j k l } do_plansql_test 4.5 { SELECT y FROM terms, x3 WHERE y = term AND occurrences>1 AND col = '*' } { - 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} - 0 1 1 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)} + QUERY PLAN + |--SCAN TABLE terms VIRTUAL TABLE INDEX 0: + `--SEARCH TABLE x3 USING COVERING INDEX i1 (y=?) +} { a k l } diff --git a/test/fts3conf.test b/test/fts3conf.test index 6766a95408..6ceef2c47e 100644 --- a/test/fts3conf.test +++ b/test/fts3conf.test @@ -136,47 +136,49 @@ do_execsql_test 2.2.2 { COMMIT } do_execsql_test 2.2.3 { SELECT * FROM t1 } {{a b c} {a b c}} fts3_integrity 2.2.4 db t1 -do_execsql_test 3.1 { - CREATE VIRTUAL TABLE t3 USING fts4; - REPLACE INTO t3(docid, content) VALUES (1, 'one two'); - SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one' -} {X'0100000002000000'} - -do_execsql_test 3.2 { - REPLACE INTO t3(docid, content) VALUES (2, 'one two three four'); - SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'four' -} {X'0200000003000000'} - -do_execsql_test 3.3 { - REPLACE INTO t3(docid, content) VALUES (1, 'one two three four five six'); - SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six' -} {X'0200000005000000'} - -do_execsql_test 3.4 { - UPDATE OR REPLACE t3 SET docid = 2 WHERE docid=1; - SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six' -} {X'0100000006000000'} - -do_execsql_test 3.5 { - UPDATE OR REPLACE t3 SET docid = 3 WHERE docid=2; - SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six' -} {X'0100000006000000'} - -do_execsql_test 3.6 { - REPLACE INTO t3(docid, content) VALUES (3, 'one two'); - SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one' -} {X'0100000002000000'} - -do_execsql_test 3.7 { - REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four'); - REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four five six'); - SELECT docid FROM t3; -} {3 4 5} - -do_execsql_test 3.8 { - UPDATE OR REPLACE t3 SET docid = 5, content='three four' WHERE docid = 4; - SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one' -} {X'0200000002000000'} +if {$tcl_platform(byteOrder)=="littleEndian"} { + do_execsql_test 3.1 { + CREATE VIRTUAL TABLE t3 USING fts4; + REPLACE INTO t3(docid, content) VALUES (1, 'one two'); + SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one' + } {X'0100000002000000'} + + do_execsql_test 3.2 { + REPLACE INTO t3(docid, content) VALUES (2, 'one two three four'); + SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'four' + } {X'0200000003000000'} + + do_execsql_test 3.3 { + REPLACE INTO t3(docid, content) VALUES (1, 'one two three four five six'); + SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six' + } {X'0200000005000000'} + + do_execsql_test 3.4 { + UPDATE OR REPLACE t3 SET docid = 2 WHERE docid=1; + SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six' + } {X'0100000006000000'} + + do_execsql_test 3.5 { + UPDATE OR REPLACE t3 SET docid = 3 WHERE docid=2; + SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six' + } {X'0100000006000000'} + + do_execsql_test 3.6 { + REPLACE INTO t3(docid, content) VALUES (3, 'one two'); + SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one' + } {X'0100000002000000'} + + do_execsql_test 3.7 { + REPLACE INTO t3(docid, content) VALUES(NULL,'one two three four'); + REPLACE INTO t3(docid, content) VALUES(NULL,'one two three four five six'); + SELECT docid FROM t3; + } {3 4 5} + + do_execsql_test 3.8 { + UPDATE OR REPLACE t3 SET docid = 5, content='three four' WHERE docid = 4; + SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one' + } {X'0200000002000000'} +} #------------------------------------------------------------------------- # Test that the xSavepoint is invoked correctly if the first write diff --git a/test/fts3expr.test b/test/fts3expr.test index b186a157d1..2fd19201b6 100644 --- a/test/fts3expr.test +++ b/test/fts3expr.test @@ -409,7 +409,7 @@ do_test fts3expr-5.1 { } {1 {Usage: fts3_exprtest(tokenizer, expr, col1, ...}} do_test fts3expr-5.2 { catchsql { SELECT fts3_exprtest('doesnotexist', 'a b', 'c') } -} {1 {No such tokenizer module}} +} {1 {unknown tokenizer: doesnotexist}} do_test fts3expr-5.3 { catchsql { SELECT fts3_exprtest('simple', 'a b OR', 'c') } } {1 {Error parsing expression}} diff --git a/test/fts3expr4.test b/test/fts3expr4.test index 9fc22c1172..1bf039e55f 100644 --- a/test/fts3expr4.test +++ b/test/fts3expr4.test @@ -29,7 +29,8 @@ proc test_fts3expr {tokenizer expr} { } proc do_icu_expr_test {tn expr res} { - uplevel [list do_test $tn [list test_fts3expr icu $expr] [list {*}$res]] + set res2 [list {*}$res] + uplevel [list do_test $tn [list test_fts3expr "icu en_US" $expr] $res2] } proc do_simple_expr_test {tn expr res} { diff --git a/test/fts3join.test b/test/fts3join.test index 0eb7f47c69..f3b9b3639a 100644 --- a/test/fts3join.test +++ b/test/fts3join.test @@ -96,9 +96,11 @@ do_eqp_test 4.2 { ) AS rr ON t4.rowid=rr.docid WHERE t4.y = ?; } { - 1 0 0 {SCAN TABLE ft4 VIRTUAL TABLE INDEX 3:} - 0 0 0 {SCAN TABLE t4} - 0 1 1 {SEARCH SUBQUERY 1 AS rr USING AUTOMATIC COVERING INDEX (docid=?)} + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--SCAN TABLE ft4 VIRTUAL TABLE INDEX 3: + |--SCAN TABLE t4 + `--SEARCH SUBQUERY xxxxxx AS rr USING AUTOMATIC COVERING INDEX (docid=?) } finish_test diff --git a/test/fts3query.test b/test/fts3query.test index 7d5ae991f7..bc25699e12 100644 --- a/test/fts3query.test +++ b/test/fts3query.test @@ -118,26 +118,30 @@ do_test fts3query-4.1 { do_eqp_test fts3query-4.2 { SELECT t1.number FROM t1, ft WHERE t1.number=ft.rowid ORDER BY t1.date } { - 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1} - 0 1 1 {SCAN TABLE ft VIRTUAL TABLE INDEX 1:} + QUERY PLAN + |--SCAN TABLE t1 USING COVERING INDEX i1 + `--SCAN TABLE ft VIRTUAL TABLE INDEX 1: } do_eqp_test fts3query-4.3 { SELECT t1.number FROM ft, t1 WHERE t1.number=ft.rowid ORDER BY t1.date } { - 0 0 1 {SCAN TABLE t1 USING COVERING INDEX i1} - 0 1 0 {SCAN TABLE ft VIRTUAL TABLE INDEX 1:} + QUERY PLAN + |--SCAN TABLE t1 USING COVERING INDEX i1 + `--SCAN TABLE ft VIRTUAL TABLE INDEX 1: } do_eqp_test fts3query-4.4 { SELECT t1.number FROM t1, bt WHERE t1.number=bt.rowid ORDER BY t1.date } { - 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1} - 0 1 1 {SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + |--SCAN TABLE t1 USING COVERING INDEX i1 + `--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?) } do_eqp_test fts3query-4.5 { SELECT t1.number FROM bt, t1 WHERE t1.number=bt.rowid ORDER BY t1.date } { - 0 0 1 {SCAN TABLE t1 USING COVERING INDEX i1} - 0 1 0 {SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + |--SCAN TABLE t1 USING COVERING INDEX i1 + `--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?) } diff --git a/test/fts3rank.test b/test/fts3rank.test new file mode 100644 index 0000000000..fd1a1c89d7 --- /dev/null +++ b/test/fts3rank.test @@ -0,0 +1,69 @@ +# 2017 October 7 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# This file implements regression tests for SQLite library. The +# focus of this script is testing the FTS3 module. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix fts3rank + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts3 { + finish_test + return +} + +install_fts3_rank_function db +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts3(a, b); + INSERT INTO t1 VALUES('one two', 'one'); + INSERT INTO t1 VALUES('one two', 'three'); + INSERT INTO t1 VALUES('one two', 'two'); +} + +do_execsql_test 1.1 { + SELECT * FROM t1 WHERE t1 MATCH 'one' + ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid +} { + {one two} one + {one two} three + {one two} two +} + +do_execsql_test 1.2 { + SELECT * FROM t1 WHERE t1 MATCH 'two' + ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid +} { + {one two} two + {one two} one + {one two} three +} + +do_catchsql_test 1.3 { + SELECT * FROM t1 ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid +} {1 {invalid matchinfo blob passed to function rank()}} + +do_catchsql_test 1.4 { + SELECT * FROM t1 ORDER BY rank(x'0000000000000000') DESC, rowid +} {0 {{one two} one {one two} three {one two} two}} + +if {$tcl_platform(byteOrder)=="littleEndian"} { + do_catchsql_test 1.5le { + SELECT * FROM t1 ORDER BY rank(x'0100000001000000') DESC, rowid + } {1 {invalid matchinfo blob passed to function rank()}} +} else { + do_catchsql_test 1.5be { + SELECT * FROM t1 ORDER BY rank(x'0000000100000001') DESC, rowid + } {1 {invalid matchinfo blob passed to function rank()}} +} + +finish_test diff --git a/test/fts4onepass.test b/test/fts4onepass.test index 46cb4b794b..344be4b1df 100644 --- a/test/fts4onepass.test +++ b/test/fts4onepass.test @@ -143,4 +143,18 @@ foreach {tn tcl1 tcl2} { eval $tcl2 } +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE zt USING fts4(a, b); + INSERT INTO zt(rowid, a, b) VALUES(1, 'unus duo', NULL); + INSERT INTO zt(rowid, a, b) VALUES(2, NULL, NULL); + + BEGIN; + UPDATE zt SET b='septum' WHERE rowid = 1; + UPDATE zt SET b='octo' WHERE rowid = 1; + COMMIT; + + SELECT count(*) FROM zt_segdir; +} {3} + + finish_test diff --git a/test/func.test b/test/func.test index 98ae8ddeb5..23a3ae4392 100644 --- a/test/func.test +++ b/test/func.test @@ -507,6 +507,17 @@ if {$encoding=="UTF-16le"} { execsql {SELECT hex(replace('aabcdefg','a','aaa'))} } {616161616161626364656667} } +do_execsql_test func-9.14 { + WITH RECURSIVE c(x) AS ( + VALUES(1) + UNION ALL + SELECT x+1 FROM c WHERE x<1040 + ) + SELECT + count(*), + sum(length(replace(printf('abc%.*cxyz',x,'m'),'m','nnnn'))-(6+x*4)) + FROM c; +} {1040 0} # Use the "sqlite_register_test_function" TCL command which is part of # the text fixture in order to verify correct operation of some of diff --git a/test/func6.test b/test/func6.test new file mode 100644 index 0000000000..1e16a7ca38 --- /dev/null +++ b/test/func6.test @@ -0,0 +1,174 @@ +# 2017-12-16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# +# Test cases for the sqlite_offset() function. +# +# Some of the tests in this file depend on the exact placement of content +# within b-tree pages. Such placement is at the implementations discretion, +# and so it is possible for results to change from one release to the next. +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !offset_sql_func { + finish_test + return +} + +set bNullTrim 0 +ifcapable null_trim { + set bNullTrim 1 +} + +do_execsql_test func6-100 { + PRAGMA page_size=4096; + PRAGMA auto_vacuum=NONE; + CREATE TABLE t1(a,b,c,d); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c,d) SELECT printf('abc%03x',x), x, 1000-x, NULL FROM c; + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1bc ON t1(b,c); + CREATE TABLE t2(x TEXT PRIMARY KEY, y) WITHOUT ROWID; + INSERT INTO t2(x,y) SELECT a, b FROM t1; +} + +# Load the contents of $file from disk and return it encoded as a hex +# string. +proc loadhex {file} { + set fd [open $file] + fconfigure $fd -translation binary -encoding binary + set data [read $fd] + close $fd + binary encode hex $data +} + +# Each argument is either an integer between 0 and 65535, a text value, or +# an empty string representing an SQL NULL. This command builds an SQLite +# record containing the values passed as arguments and returns it encoded +# as a hex string. +proc hexrecord {args} { + set hdr "" + set body "" + + if {$::bNullTrim} { + while {[llength $args] && [lindex $args end]=={}} { + set args [lrange $args 0 end-1] + } + } + + foreach x $args { + if {$x==""} { + append hdr 00 + } elseif {[string is integer $x]==0} { + set n [string length $x] + append hdr [format %02x [expr $n*2 + 13]] + append body [binary encode hex $x] + } elseif {$x == 0} { + append hdr 08 + } elseif {$x == 1} { + append hdr 09 + } elseif {$x <= 127} { + append hdr 01 + append body [format %02x $x] + } else { + append hdr 02 + append body [format %04x $x] + } + } + set res [format %02x [expr 1 + [string length $hdr]/2]] + append res $hdr + append res $body +} + +# Argument $off is an offset into the database image encoded as a hex string +# in argument $hexdb. This command returns 0 if the offset contains the hex +# $hexrec, or throws an exception otherwise. +# +proc offset_contains_record {off hexdb hexrec} { + set n [string length $hexrec] + set off [expr $off*2] + if { [string compare $hexrec [string range $hexdb $off [expr $off+$n-1]]] } { + error "record not found!" + } + return 0 +} + +# This command is the implementation of SQL function "offrec()". The first +# argument to this is an offset value. The remaining values are used to +# formulate an SQLite record. If database file test.db does not contain +# an equivalent record at the specified offset, an exception is thrown. +# Otherwise, 0 is returned. +# +proc offrec {args} { + set offset [lindex $args 0] + set rec [hexrecord {*}[lrange $args 1 end]] + offset_contains_record $offset $::F $rec +} +set F [loadhex test.db] +db func offrec offrec + +# Test the sanity of the tests. +if {$bNullTrim} { + set offset 8180 +} else { + set offset 8179 +} +do_execsql_test func6-105 { + SELECT sqlite_offset(d) FROM t1 ORDER BY rowid LIMIT 1; +} $offset +do_test func6-106 { + set r [hexrecord abc001 1 999 {}] + offset_contains_record $offset $F $r +} 0 + +set z100 [string trim [string repeat "0 " 100]] + +# Test offsets within table b-tree t1. +do_execsql_test func6-110 { + SELECT offrec(sqlite_offset(d), a, b, c, d) FROM t1 ORDER BY rowid +} $z100 + +do_execsql_test func6-120 { + SELECT a, typeof(sqlite_offset(+a)) FROM t1 + ORDER BY rowid LIMIT 2; +} {abc001 null abc002 null} + +# Test offsets within index b-tree t1a. +do_execsql_test func6-130 { + SELECT offrec(sqlite_offset(a), a, rowid) FROM t1 ORDER BY a +} $z100 + +# Test offsets within table b-tree t1 with a temp b-tree ORDER BY. +do_execsql_test func6-140 { + SELECT offrec(sqlite_offset(d), a, b, c, d) FROM t1 ORDER BY a +} $z100 + +# Test offsets from both index t1a and table t1 in the same query. +do_execsql_test func6-150 { + SELECT offrec(sqlite_offset(a), a, rowid), + offrec(sqlite_offset(d), a, b, c, d) + FROM t1 ORDER BY a +} [concat $z100 $z100] + +# Test offsets from both index t1bc and table t1 in the same query. +do_execsql_test func6-160 { + SELECT offrec(sqlite_offset(b), b, c, rowid), + offrec(sqlite_offset(c), b, c, rowid), + offrec(sqlite_offset(d), a, b, c, d) + FROM t1 + ORDER BY b +} [concat $z100 $z100 $z100] + +# Test offsets in WITHOUT ROWID table t2. +do_execsql_test func6-200 { + SELECT offrec( sqlite_offset(y), x, y ) FROM t2 ORDER BY x +} $z100 + +finish_test diff --git a/test/fuzz_malloc.test b/test/fuzz_malloc.test index 1e31babd92..4449ea8fc4 100644 --- a/test/fuzz_malloc.test +++ b/test/fuzz_malloc.test @@ -17,11 +17,6 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -ifcapable !memdebug { - finish_test - return -} - source $testdir/malloc_common.tcl source $testdir/fuzz_common.tcl @@ -57,9 +52,20 @@ proc do_fuzzy_malloc_test {testname args} { incr jj set ::sql [subst $::fuzzyopts(-template)] # puts fuzyy-sql=\[$::sql\]; flush stdout - foreach {rc res} [catchsql "$::sql"] {} + foreach {rc ::fmtres} [catchsql "$::sql"] {} if {$rc==0} { - do_malloc_test $testname-$ii -sqlbody $::sql -sqlprep $::prep + set nErr1 [set_test_counter errors] + do_faultsim_test $testname-$ii -faults oom* -body { + execsql $::sql + } -test { + if {$testrc && $testresult!="datatype mismatch"} { + faultsim_test_result {0 {}} + } + } + if {[set_test_counter errors]>$nErr1} { + puts "Previous fuzzy-sql=\[$::sql\]" + flush stdout + } } else { incr ii -1 } diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index fd72273f34..85126e19a8 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -81,7 +81,13 @@ #ifdef SQLITE_OSS_FUZZ # include -# include +# if !defined(_MSC_VER) +# include +# endif +#endif + +#if defined(_MSC_VER) +typedef unsigned char uint8_t; #endif /* @@ -714,11 +720,13 @@ static void rebuild_database(sqlite3 *db){ "BEGIN;\n" "CREATE TEMP TABLE dbx AS SELECT DISTINCT dbcontent FROM db;\n" "DELETE FROM db;\n" - "INSERT INTO db(dbid, dbcontent) SELECT NULL, dbcontent FROM dbx ORDER BY 2;\n" + "INSERT INTO db(dbid, dbcontent) " + " SELECT NULL, dbcontent FROM dbx ORDER BY 2;\n" "DROP TABLE dbx;\n" "CREATE TEMP TABLE sx AS SELECT DISTINCT sqltext FROM xsql;\n" "DELETE FROM xsql;\n" - "INSERT INTO xsql(sqlid,sqltext) SELECT NULL, sqltext FROM sx ORDER BY 2;\n" + "INSERT INTO xsql(sqlid,sqltext) " + " SELECT NULL, sqltext FROM sx ORDER BY 2;\n" "DROP TABLE sx;\n" "COMMIT;\n" "PRAGMA page_size=1024;\n" @@ -798,16 +806,17 @@ static void showHelp(void){ " --export-db DIR Write databases to files(s) in DIR. Works with --dbid\n" " --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n" " --help Show this help text\n" -" -q|--quiet Reduced output\n" +" --info Show information about SOURCE-DB w/o running tests\n" " --limit-mem N Limit memory used by test SQLite instance to N bytes\n" " --limit-vdbe Panic if any test runs for more than 100,000 cycles\n" -" --load-sql ARGS... Load SQL scripts fro files into SOURCE-DB\n" +" --load-sql ARGS... Load SQL scripts fron files into SOURCE-DB\n" " --load-db ARGS... Load template databases from files into SOURCE_DB\n" " -m TEXT Add a description to the database\n" " --native-vfs Use the native VFS for initially empty database files\n" " --native-malloc Turn off MEMSYS3/5 and Lookaside\n" " --oss-fuzz Enable OSS-FUZZ testing\n" " --prng-seed N Seed value for the PRGN inside of SQLite\n" +" -q|--quiet Reduced output\n" " --rebuild Rebuild and vacuum the database file\n" " --result-trace Show the results of each SQL command\n" " --sqlid N Use only SQL where sqlid=N\n" @@ -821,7 +830,7 @@ int main(int argc, char **argv){ 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 */ + int iFirstInsArg = 0; /* First argv[] 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 */ @@ -833,6 +842,7 @@ int main(int argc, char **argv){ int nativeFlag = 0; /* --native-vfs */ int rebuildFlag = 0; /* --rebuild */ int vdbeLimitFlag = 0; /* --limit-vdbe */ + int infoFlag = 0; /* --info */ int timeoutTest = 0; /* undocumented --timeout-test flag */ int runFlags = 0; /* Flags sent to runSql() */ char *zMsg = 0; /* Add this message */ @@ -841,9 +851,9 @@ int main(int argc, char **argv){ 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 */ + const char *zFailCode = 0; /* Value of the TEST_FAILURE env variable */ int cellSzCkFlag = 0; /* --cell-size-check */ - int sqlFuzz = 0; /* True for SQL fuzz testing. False for DB fuzz */ + int sqlFuzz = 0; /* True for SQL fuzz. False for DB fuzz */ int iTimeout = 120; /* Default 120-second timeout */ int nMem = 0; /* Memory limit */ int nMemThisDb = 0; /* Memory limit set by the CONFIG table */ @@ -854,12 +864,14 @@ int main(int argc, char **argv){ int ossFuzzThisDb = 0; /* ossFuzz value for this particular database */ int nativeMalloc = 0; /* Turn off MEMSYS3/5 and lookaside if true */ sqlite3_vfs *pDfltVfs; /* The default VFS */ + int openFlags4Data; /* Flags for sqlite3_open_v2() */ iBegin = timeOfDay(); #ifdef __unix__ signal(SIGALRM, timeoutHandler); #endif g.zArgv0 = argv[0]; + openFlags4Data = SQLITE_OPEN_READONLY; zFailCode = getenv("TEST_FAILURE"); pDfltVfs = sqlite3_vfs_find(0); inmemVfsRegister(1); @@ -887,6 +899,9 @@ int main(int argc, char **argv){ showHelp(); return 0; }else + if( strcmp(z,"info")==0 ){ + infoFlag = 1; + }else if( strcmp(z,"limit-mem")==0 ){ #if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5) fatalError("the %s option requires -DSQLITE_ENABLE_MEMSYS5 or _MEMSYS3", @@ -900,18 +915,21 @@ int main(int argc, char **argv){ vdbeLimitFlag = 1; }else if( strcmp(z,"load-sql")==0 ){ - zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))"; + zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))"; iFirstInsArg = i+1; + openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; break; }else if( strcmp(z,"load-db")==0 ){ zInsSql = "INSERT INTO db(dbcontent) VALUES(readfile(?1))"; iFirstInsArg = i+1; + openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; break; }else if( strcmp(z,"m")==0 ){ if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); zMsg = argv[++i]; + openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; }else if( strcmp(z,"native-malloc")==0 ){ nativeMalloc = 1; @@ -932,6 +950,7 @@ int main(int argc, char **argv){ }else if( strcmp(z,"rebuild")==0 ){ rebuildFlag = 1; + openFlags4Data = SQLITE_OPEN_READWRITE; }else if( strcmp(z,"result-trace")==0 ){ runFlags |= SQL_OUTPUT; @@ -977,11 +996,47 @@ int main(int argc, char **argv){ /* Process each source database separately */ for(iSrcDb=0; iSrcDbzName); + openFlags4Data, pDfltVfs->zName); if( rc ){ fatalError("cannot open source database %s - %s", azSrcDb[iSrcDb], sqlite3_errmsg(db)); } + + /* Print the description, if there is one */ + if( infoFlag ){ + int n; + zDbName = azSrcDb[iSrcDb]; + i = (int)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", zDbName, sqlite3_column_text(pStmt,0)); + }else{ + printf("%s: (empty \"readme\")", zDbName); + } + sqlite3_finalize(pStmt); + sqlite3_prepare_v2(db, "SELECT count(*) FROM db", -1, &pStmt, 0); + if( pStmt + && sqlite3_step(pStmt)==SQLITE_ROW + && (n = sqlite3_column_int(pStmt,0))>0 + ){ + printf(" - %d DBs", n); + } + sqlite3_finalize(pStmt); + sqlite3_prepare_v2(db, "SELECT count(*) FROM xsql", -1, &pStmt, 0); + if( pStmt + && sqlite3_step(pStmt)==SQLITE_ROW + && (n = sqlite3_column_int(pStmt,0))>0 + ){ + printf(" - %d scripts", n); + } + sqlite3_finalize(pStmt); + printf("\n"); + sqlite3_close(db); + continue; + } + rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS db(\n" " dbid INTEGER PRIMARY KEY, -- database id\n" @@ -1008,7 +1063,8 @@ int main(int argc, char **argv){ /* If the CONFIG(name,value) table exists, read db-specific settings ** from that table */ if( sqlite3_table_column_metadata(db,0,"config",0,0,0,0,0,0)==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, "SELECT name, value FROM config", -1, &pStmt, 0); + rc = sqlite3_prepare_v2(db, "SELECT name, value FROM config", + -1, &pStmt, 0); if( rc ) fatalError("cannot prepare query of CONFIG table: %s", sqlite3_errmsg(db)); while( SQLITE_ROW==sqlite3_step(pStmt) ){ @@ -1047,7 +1103,8 @@ int main(int argc, char **argv){ } sqlite3_finalize(pStmt); rc = sqlite3_exec(db, "COMMIT", 0, 0, 0); - if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db)); + if( rc ) fatalError("cannot commit the transaction: %s", + sqlite3_errmsg(db)); rebuild_database(db); sqlite3_close(db); return 0; @@ -1191,7 +1248,8 @@ int main(int argc, char **argv){ sqlite3_randomness(0,0); if( ossFuzzThisDb ){ #ifndef SQLITE_OSS_FUZZ - fatalError("--oss-fuzz not supported: recompile with -DSQLITE_OSS_FUZZ"); + fatalError("--oss-fuzz not supported: recompile" + " with -DSQLITE_OSS_FUZZ"); #else extern int LLVMFuzzerTestOneInput(const uint8_t*, size_t); LLVMFuzzerTestOneInput((const uint8_t*)pSql->a, (size_t)pSql->sz); @@ -1210,7 +1268,8 @@ int main(int argc, char **argv){ setAlarm(iTimeout); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( sqlFuzz || vdbeLimitFlag ){ - sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); + sqlite3_progress_handler(db, 100000, progressHandler, + &vdbeLimitFlag); } #endif do{ diff --git a/test/fuzzdata2.db b/test/fuzzdata2.db index 598814622c..7682790046 100644 Binary files a/test/fuzzdata2.db and b/test/fuzzdata2.db differ diff --git a/test/fuzzdata4.db b/test/fuzzdata4.db index b97ca104e7..254bf834ff 100644 Binary files a/test/fuzzdata4.db and b/test/fuzzdata4.db differ diff --git a/test/fuzzdata5.db b/test/fuzzdata5.db index 4645b1921b..cfb0ebe7d8 100644 Binary files a/test/fuzzdata5.db and b/test/fuzzdata5.db differ diff --git a/test/fuzzdata6.db b/test/fuzzdata6.db new file mode 100644 index 0000000000..b1424c21e4 Binary files /dev/null and b/test/fuzzdata6.db differ diff --git a/test/having.test b/test/having.test index aea12319d7..a3882552d3 100644 --- a/test/having.test +++ b/test/having.test @@ -65,19 +65,6 @@ foreach {tn sql1 sql2} { 3 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING a=2" "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a COLLATE binary" - 4 { - SELECT x,y FROM ( - SELECT a AS x, sum(b) AS y FROM t1 - GROUP BY a - ) WHERE x BETWEEN 8888 AND 9999 - } { - SELECT x,y FROM ( - SELECT a AS x, sum(b) AS y FROM t1 - WHERE x BETWEEN 8888 AND 9999 - GROUP BY a - ) - } - 5 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING 0" "SELECT a, sum(b) FROM t1 WHERE 0 GROUP BY a COLLATE binary" @@ -98,6 +85,24 @@ foreach {tn sql1 sql2} { do_compare_vdbe_test 2.$tn $sql1 $sql2 1 } +# The (4) test in the above set used to generate identical bytecode, but +# that is no longer the case. The byte code is equivalent, though. +# +do_execsql_test 2.4a { + SELECT x,y FROM ( + SELECT a AS x, sum(b) AS y FROM t1 + GROUP BY a + ) WHERE x BETWEEN 2 AND 9999 +} {2 12} +do_execsql_test 2.4b { + SELECT x,y FROM ( + SELECT a AS x, sum(b) AS y FROM t1 + WHERE x BETWEEN 2 AND 9999 + GROUP BY a + ) +} {2 12} + + #------------------------------------------------------------------------- # 1: Test that the optimization is only applied if the GROUP BY term # uses BINARY collation. diff --git a/test/hook.test b/test/hook.test index 9ba220cded..1c9145baef 100644 --- a/test/hook.test +++ b/test/hook.test @@ -906,5 +906,56 @@ do_preupdate_test 10.3 { DELETE FROM t3 WHERE b=1 } {DELETE main t3 1 1 0 {} 1} +#------------------------------------------------------------------------- +# Test that the "update" hook is not fired for operations on the +# sqlite_stat1 table performed by ANALYZE, even if a pre-update hook is +# registered. +ifcapable analyze { + reset_db + do_execsql_test 11.1 { + CREATE TABLE t1(a, b); + CREATE INDEX idx1 ON t1(a); + CREATE INDEX idx2 ON t1(b); + + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + } + + db preupdate hook preupdate_cb + db update_hook update_cb + + proc preupdate_cb {args} { lappend ::res "preupdate" $args } + proc update_cb {args} { lappend ::res "update" $args } + + set ::res [list] + do_test 11.2 { + execsql ANALYZE + set ::res + } [list {*}{ + preupdate {INSERT main sqlite_stat1 1 1} + preupdate {INSERT main sqlite_stat1 2 2} + }] + + do_execsql_test 11.3 { + INSERT INTO t1 VALUES(9, 10); + INSERT INTO t1 VALUES(11, 12); + INSERT INTO t1 VALUES(13, 14); + INSERT INTO t1 VALUES(15, 16); + } + + set ::res [list] + do_test 11.4 { + execsql ANALYZE + set ::res + } [list {*}{ + preupdate {DELETE main sqlite_stat1 1 1} + preupdate {DELETE main sqlite_stat1 2 2} + preupdate {INSERT main sqlite_stat1 1 1} + preupdate {INSERT main sqlite_stat1 2 2} + }] +} + finish_test diff --git a/test/icu.test b/test/icu.test index 743bcfaea1..4c4e6d14ec 100644 --- a/test/icu.test +++ b/test/icu.test @@ -15,7 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -ifcapable !icu { +ifcapable !icu&&!icu_collations { finish_test return } @@ -35,54 +35,57 @@ proc test_expr {name settings expr result} { } $settings $expr] $result } -# Tests of the REGEXP operator. -# -test_expr icu-1.1 {i1='hello'} {i1 REGEXP 'hello'} 1 -test_expr icu-1.2 {i1='hello'} {i1 REGEXP '.ello'} 1 -test_expr icu-1.3 {i1='hello'} {i1 REGEXP '.ell'} 0 -test_expr icu-1.4 {i1='hello'} {i1 REGEXP '.ell.*'} 1 -test_expr icu-1.5 {i1=NULL} {i1 REGEXP '.ell.*'} {} +ifcapable icu { -# Some non-ascii characters with defined case mappings -# -set ::EGRAVE "\xC8" -set ::egrave "\xE8" + # Tests of the REGEXP operator. + # + test_expr icu-1.1 {i1='hello'} {i1 REGEXP 'hello'} 1 + test_expr icu-1.2 {i1='hello'} {i1 REGEXP '.ello'} 1 + test_expr icu-1.3 {i1='hello'} {i1 REGEXP '.ell'} 0 + test_expr icu-1.4 {i1='hello'} {i1 REGEXP '.ell.*'} 1 + test_expr icu-1.5 {i1=NULL} {i1 REGEXP '.ell.*'} {} -set ::OGRAVE "\xD2" -set ::ograve "\xF2" + # Some non-ascii characters with defined case mappings + # + set ::EGRAVE "\xC8" + set ::egrave "\xE8" -# That German letter that looks a bit like a B. The -# upper-case version of which is "SS" (two characters). -# -set ::szlig "\xDF" + set ::OGRAVE "\xD2" + set ::ograve "\xF2" -# Tests of the upper()/lower() functions. -# -test_expr icu-2.1 {i1='HellO WorlD'} {upper(i1)} {HELLO WORLD} -test_expr icu-2.2 {i1='HellO WorlD'} {lower(i1)} {hello world} -test_expr icu-2.3 {i1=$::egrave} {lower(i1)} $::egrave -test_expr icu-2.4 {i1=$::egrave} {upper(i1)} $::EGRAVE -test_expr icu-2.5 {i1=$::ograve} {lower(i1)} $::ograve -test_expr icu-2.6 {i1=$::ograve} {upper(i1)} $::OGRAVE -test_expr icu-2.3 {i1=$::EGRAVE} {lower(i1)} $::egrave -test_expr icu-2.4 {i1=$::EGRAVE} {upper(i1)} $::EGRAVE -test_expr icu-2.5 {i1=$::OGRAVE} {lower(i1)} $::ograve -test_expr icu-2.6 {i1=$::OGRAVE} {upper(i1)} $::OGRAVE + # That German letter that looks a bit like a B. The + # upper-case version of which is "SS" (two characters). + # + set ::szlig "\xDF" -test_expr icu-2.7 {i1=$::szlig} {upper(i1)} "SS" -test_expr icu-2.8 {i1='SS'} {lower(i1)} "ss" + # Tests of the upper()/lower() functions. + # + test_expr icu-2.1 {i1='HellO WorlD'} {upper(i1)} {HELLO WORLD} + test_expr icu-2.2 {i1='HellO WorlD'} {lower(i1)} {hello world} + test_expr icu-2.3 {i1=$::egrave} {lower(i1)} $::egrave + test_expr icu-2.4 {i1=$::egrave} {upper(i1)} $::EGRAVE + test_expr icu-2.5 {i1=$::ograve} {lower(i1)} $::ograve + test_expr icu-2.6 {i1=$::ograve} {upper(i1)} $::OGRAVE + test_expr icu-2.3 {i1=$::EGRAVE} {lower(i1)} $::egrave + test_expr icu-2.4 {i1=$::EGRAVE} {upper(i1)} $::EGRAVE + test_expr icu-2.5 {i1=$::OGRAVE} {lower(i1)} $::ograve + test_expr icu-2.6 {i1=$::OGRAVE} {upper(i1)} $::OGRAVE -do_execsql_test icu-2.9 { - SELECT upper(char(0xfb04,0xfb04,0xfb04,0xfb04)); -} {FFLFFLFFLFFL} + test_expr icu-2.7 {i1=$::szlig} {upper(i1)} "SS" + test_expr icu-2.8 {i1='SS'} {lower(i1)} "ss" -# In turkish (locale="tr_TR"), the lower case version of I -# is "small dotless i" (code point 0x131 (decimal 305)). -# -set ::small_dotless_i "\u0131" -test_expr icu-3.1 {i1='I'} {lower(i1)} "i" -test_expr icu-3.2 {i1='I'} {lower(i1, 'tr_tr')} $::small_dotless_i -test_expr icu-3.3 {i1='I'} {lower(i1, 'en_AU')} "i" + do_execsql_test icu-2.9 { + SELECT upper(char(0xfb04,0xfb04,0xfb04,0xfb04)); + } {FFLFFLFFLFFL} + + # In turkish (locale="tr_TR"), the lower case version of I + # is "small dotless i" (code point 0x131 (decimal 305)). + # + set ::small_dotless_i "\u0131" + test_expr icu-3.1 {i1='I'} {lower(i1)} "i" + test_expr icu-3.2 {i1='I'} {lower(i1, 'tr_tr')} $::small_dotless_i + test_expr icu-3.3 {i1='I'} {lower(i1, 'en_AU')} "i" +} #-------------------------------------------------------------------- # Test the collation sequence function. @@ -124,22 +127,23 @@ do_test icu-4.3 { # # http://src.chromium.org/viewvc/chrome/trunk/src/third_party/sqlite/icu-regexp.patch?revision=34807&view=markup # -do_catchsql_test icu-5.1 { SELECT regexp('a[abc]c.*', 'abc') } {0 1} -do_catchsql_test icu-5.2 { - SELECT regexp('a[abc]c.*') -} {1 {wrong number of arguments to function regexp()}} -do_catchsql_test icu-5.3 { - SELECT regexp('a[abc]c.*', 'abc', 'c') -} {1 {wrong number of arguments to function regexp()}} -do_catchsql_test icu-5.4 { - SELECT 'abc' REGEXP 'a[abc]c.*' -} {0 1} -do_catchsql_test icu-5.4 { SELECT 'abc' REGEXP } {1 {near " ": syntax error}} -do_catchsql_test icu-5.5 { SELECT 'abc' REGEXP, 1 } {1 {near ",": syntax error}} - - -do_malloc_test icu-6.10 -sqlbody { - SELECT upper(char(0xfb04,0xdf,0xfb04,0xe8,0xfb04)); +ifcapable icu { + do_catchsql_test icu-5.1 { SELECT regexp('a[abc]c.*', 'abc') } {0 1} + do_catchsql_test icu-5.2 { + SELECT regexp('a[abc]c.*') + } {1 {wrong number of arguments to function regexp()}} + do_catchsql_test icu-5.3 { + SELECT regexp('a[abc]c.*', 'abc', 'c') + } {1 {wrong number of arguments to function regexp()}} + do_catchsql_test icu-5.4 { + SELECT 'abc' REGEXP 'a[abc]c.*' + } {0 1} + do_catchsql_test icu-5.5 {SELECT 'abc' REGEXP } {1 {incomplete input}} + do_catchsql_test icu-5.6 {SELECT 'abc' REGEXP, 1} {1 {near ",": syntax error}} + + do_malloc_test icu-6.10 -sqlbody { + SELECT upper(char(0xfb04,0xdf,0xfb04,0xe8,0xfb04)); + } } finish_test diff --git a/test/in6.test b/test/in6.test new file mode 100644 index 0000000000..773ee589d4 --- /dev/null +++ b/test/in6.test @@ -0,0 +1,80 @@ +# 2018-06-07 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# A multi-key index that uses an IN operator on one of the keys other +# than the left-most key is able to abort the IN-operator loop early +# if key terms further to the left do not match. +# +# Call this the "multikey-IN-operator early-out optimization" or +# just "IN-early-out" optimization for short. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix in6 + +do_test in6-1.1 { + db eval { + CREATE TABLE t1(a,b,c,d); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c,d) + SELECT 100, 200+x/2, 300+x/5, x FROM c; + CREATE INDEX t1abc ON t1(a,b,c); + ANALYZE; + UPDATE sqlite_stat1 SET stat='1000000 500000 500 50'; + ANALYZE sqlite_master; + } + set ::sqlite_search_count 0 + db eval { + SELECT d FROM t1 + WHERE a=99 + AND b IN (200,205,201,204) + AND c IN (304,302,309,308); + } +} {} +do_test in6-1.2 { + set ::sqlite_search_count +} {0} ;# Without the IN-early-out optimization, this value would be 15 + +# The multikey-IN-operator early-out optimization does not apply +# when the IN operator is on the left-most column of the index. +# +do_test in6-1.3 { + db eval { + EXPLAIN + SELECT d FROM t1 + WHERE a IN (98,99,100,101) + AND b=200 AND c=300; + } +} {~/(IfNoHope|SeekHit)/} + +set sqlite_search_count 0 +do_execsql_test in6-1.4 { + SELECT d FROM t1 + WHERE a=100 + AND b IN (200,201,202,204) + AND c IN (300,302,301,305) + ORDER BY +d; +} {1 2 3 4 5 8 9} +do_test in6-1.5 { + set ::sqlite_search_count +} {39} + +do_execsql_test in6-2.1 { + CREATE TABLE t2(e INT UNIQUE, f TEXT); + SELECT d, f FROM t1 LEFT JOIN t2 ON (e=d) + WHERE a=100 + AND b IN (200,201,202,204) + AND c IN (300,302,301,305) + ORDER BY +d; +} {1 {} 2 {} 3 {} 4 {} 5 {} 8 {} 9 {}} + +finish_test diff --git a/test/incrblob_err.test b/test/incrblob_err.test index 0db8b0dcba..3c523319c2 100644 --- a/test/incrblob_err.test +++ b/test/incrblob_err.test @@ -16,7 +16,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix incrblob_err -ifcapable {!incrblob || !memdebug || !tclvar} { +ifcapable {!incrblob || !tclvar} { finish_test return } diff --git a/test/index6.test b/test/index6.test index f6177b44e9..4ddce453fd 100644 --- a/test/index6.test +++ b/test/index6.test @@ -318,8 +318,9 @@ do_execsql_test index6-8.0 { do_eqp_test index6-8.1 { SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a) } { - 0 0 0 {SCAN TABLE t8a} - 0 1 1 {SEARCH TABLE t8b USING INDEX i8c (y=?)} + QUERY PLAN + |--SCAN TABLE t8a + `--SEARCH TABLE t8b USING INDEX i8c (y=?) } do_execsql_test index6-8.2 { diff --git a/test/index7.test b/test/index7.test index 0037a8a44d..aa0cf8c1f7 100644 --- a/test/index7.test +++ b/test/index7.test @@ -321,9 +321,8 @@ do_execsql_test index7-6.3 { } do_eqp_test index7-6.4 { SELECT * FROM v4 WHERE d='xyz' AND c='def' -} { - 0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)} -} +} {SEARCH TABLE t4 USING INDEX i4 (c=?)} + do_catchsql_test index7-6.5 { CREATE INDEX t5a ON t5(a) WHERE a=#1; } {1 {near "#1": syntax error}} diff --git a/test/indexedby.test b/test/indexedby.test index 83c7a5cccc..8624b10c75 100644 --- a/test/indexedby.test +++ b/test/indexedby.test @@ -40,17 +40,18 @@ proc EQP {sql} { # These tests are to check that "EXPLAIN QUERY PLAN" is working as expected. # -do_execsql_test indexedby-1.2 { - EXPLAIN QUERY PLAN select * from t1 WHERE a = 10; -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} -do_execsql_test indexedby-1.3 { - EXPLAIN QUERY PLAN select * from t1 ; -} {0 0 0 {SCAN TABLE t1}} -do_execsql_test indexedby-1.4 { - EXPLAIN QUERY PLAN select * from t1, t2 WHERE c = 10; +do_eqp_test indexedby-1.2 { + select * from t1 WHERE a = 10; +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} +do_eqp_test indexedby-1.3 { + select * from t1 ; +} {SCAN TABLE t1} +do_eqp_test indexedby-1.4 { + select * from t1, t2 WHERE c = 10; } { - 0 0 1 {SEARCH TABLE t2 USING INDEX i3 (c=?)} - 0 1 0 {SCAN TABLE t1} + QUERY PLAN + |--SEARCH TABLE t2 USING INDEX i3 (c=?) + `--SCAN TABLE t1 } # Parser tests. Test that an INDEXED BY or NOT INDEX clause can be @@ -58,7 +59,7 @@ do_execsql_test indexedby-1.4 { # SQL view. Also test that specifying an index that does not exist or # is attached to a different table is detected as an error. # -# EVIDENCE-OF: R-07004-11522 -- syntax diagram qualified-table-name +# X-EVIDENCE-OF: R-07004-11522 -- syntax diagram qualified-table-name # # EVIDENCE-OF: R-58230-57098 The "INDEXED BY index-name" phrase # specifies that the named index must be used in order to look up values @@ -115,25 +116,23 @@ do_test indexedby-2.7 { # the rowid can still be used to look up entries even when "NOT INDEXED" # is specified. # -do_execsql_test indexedby-3.1 { - EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a = 'one' AND b = 'two' +do_eqp_test indexedby-3.1 { + SELECT * FROM t1 WHERE a = 'one' AND b = 'two' } {/SEARCH TABLE t1 USING INDEX/} -do_execsql_test indexedby-3.1.1 { - EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two' -} {0 0 0 {SCAN TABLE t1}} -do_execsql_test indexedby-3.1.2 { - EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE rowid=1 +do_eqp_test indexedby-3.1.1 { + SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two' +} {SCAN TABLE t1} +do_eqp_test indexedby-3.1.2 { + SELECT * FROM t1 NOT INDEXED WHERE rowid=1 } {/SEARCH TABLE t1 USING INTEGER PRIMARY KEY .rowid=/} -do_execsql_test indexedby-3.2 { - EXPLAIN QUERY PLAN +do_eqp_test indexedby-3.2 { SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two' -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} -do_execsql_test indexedby-3.3 { - EXPLAIN QUERY PLAN +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} +do_eqp_test indexedby-3.3 { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two' -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}} +} {SEARCH TABLE t1 USING INDEX i2 (b=?)} do_test indexedby-3.4 { catchsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' } } {1 {no query solution}} @@ -147,14 +146,12 @@ do_test indexedby-3.7 { catchsql { SELECT * FROM t1 INDEXED BY i1 ORDER BY a } } {0 {}} -do_execsql_test indexedby-3.8 { - EXPLAIN QUERY PLAN +do_eqp_test indexedby-3.8 { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 ORDER BY e -} {0 0 0 {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1}} -do_execsql_test indexedby-3.9 { - EXPLAIN QUERY PLAN +} {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1} +do_eqp_test indexedby-3.9 { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE e = 10 -} {0 0 0 {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?)}} +} {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?)} do_test indexedby-3.10 { catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE f = 10 } } {1 {no query solution}} @@ -164,17 +161,19 @@ do_test indexedby-3.11 { # Tests for multiple table cases. # -do_execsql_test indexedby-4.1 { - EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE a = c +do_eqp_test indexedby-4.1 { + SELECT * FROM t1, t2 WHERE a = c } { - 0 0 0 {SCAN TABLE t1} - 0 1 1 {SEARCH TABLE t2 USING INDEX i3 (c=?)} + QUERY PLAN + |--SCAN TABLE t1 + `--SEARCH TABLE t2 USING INDEX i3 (c=?) } -do_execsql_test indexedby-4.2 { - EXPLAIN QUERY PLAN SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c +do_eqp_test indexedby-4.2 { + SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c } { - 0 0 1 {SCAN TABLE t2} - 0 1 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)} + QUERY PLAN + |--SCAN TABLE t2 + `--SEARCH TABLE t1 USING INDEX i1 (a=?) } do_test indexedby-4.3 { catchsql { @@ -194,10 +193,10 @@ do_test indexedby-4.4 { do_execsql_test indexedby-5.1 { CREATE VIEW v2 AS SELECT * FROM t1 INDEXED BY i1 WHERE a > 5; EXPLAIN QUERY PLAN SELECT * FROM v2 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}} +} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/} do_execsql_test indexedby-5.2 { EXPLAIN QUERY PLAN SELECT * FROM v2 WHERE b = 10 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}} +} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/} do_test indexedby-5.3 { execsql { DROP INDEX i1 } catchsql { SELECT * FROM v2 } @@ -216,12 +215,12 @@ do_test indexedby-5.5 { # Test that "NOT INDEXED" may use the rowid index, but not others. # -do_execsql_test indexedby-6.1 { - EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 10 ORDER BY rowid -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}} -do_execsql_test indexedby-6.2 { - EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid -} {0 0 0 {SCAN TABLE t1}} +do_eqp_test indexedby-6.1 { + SELECT * FROM t1 WHERE b = 10 ORDER BY rowid +} {SEARCH TABLE t1 USING INDEX i2 (b=?)} +do_eqp_test indexedby-6.2 { + SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid +} {SCAN TABLE t1} # EVIDENCE-OF: R-40297-14464 The INDEXED BY phrase forces the SQLite # query planner to use a particular named index on a DELETE, SELECT, or @@ -229,44 +228,42 @@ do_execsql_test indexedby-6.2 { # # Test that "INDEXED BY" can be used in a DELETE statement. # -do_execsql_test indexedby-7.1 { - EXPLAIN QUERY PLAN DELETE FROM t1 WHERE a = 5 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} -do_execsql_test indexedby-7.2 { - EXPLAIN QUERY PLAN DELETE FROM t1 NOT INDEXED WHERE a = 5 -} {0 0 0 {SCAN TABLE t1}} -do_execsql_test indexedby-7.3 { - EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} -do_execsql_test indexedby-7.4 { - EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} -do_execsql_test indexedby-7.5 { - EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}} +do_eqp_test indexedby-7.1 { + DELETE FROM t1 WHERE a = 5 +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} +do_eqp_test indexedby-7.2 { + DELETE FROM t1 NOT INDEXED WHERE a = 5 +} {SCAN TABLE t1} +do_eqp_test indexedby-7.3 { + DELETE FROM t1 INDEXED BY i1 WHERE a = 5 +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} +do_eqp_test indexedby-7.4 { + DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10 +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} +do_eqp_test indexedby-7.5 { + DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10 +} {SEARCH TABLE t1 USING INDEX i2 (b=?)} do_test indexedby-7.6 { catchsql { DELETE FROM t1 INDEXED BY i2 WHERE a = 5} } {1 {no query solution}} # Test that "INDEXED BY" can be used in an UPDATE statement. # -do_execsql_test indexedby-8.1 { - EXPLAIN QUERY PLAN UPDATE t1 SET rowid=rowid+1 WHERE a = 5 -} {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}} -do_execsql_test indexedby-8.2 { - EXPLAIN QUERY PLAN UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5 -} {0 0 0 {SCAN TABLE t1}} -do_execsql_test indexedby-8.3 { - EXPLAIN QUERY PLAN UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 -} {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}} -do_execsql_test indexedby-8.4 { - EXPLAIN QUERY PLAN +do_eqp_test indexedby-8.1 { + UPDATE t1 SET rowid=rowid+1 WHERE a = 5 +} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)} +do_eqp_test indexedby-8.2 { + UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5 +} {SCAN TABLE t1} +do_eqp_test indexedby-8.3 { + UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 +} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)} +do_eqp_test indexedby-8.4 { UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 AND b = 10 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} -do_execsql_test indexedby-8.5 { - EXPLAIN QUERY PLAN +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} +do_eqp_test indexedby-8.5 { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5 AND b = 10 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}} +} {SEARCH TABLE t1 USING INDEX i2 (b=?)} do_test indexedby-8.6 { catchsql { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5} } {1 {no query solution}} @@ -341,7 +338,7 @@ do_execsql_test 11.4 { } {1 1 3} do_eqp_test 11.5 { SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0'; -} {0 0 0 {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)}} +} {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)} do_execsql_test 11.6 { CREATE TABLE x2(c INTEGER PRIMARY KEY, a, b TEXT); @@ -362,6 +359,27 @@ do_execsql_test 11.9 { } {1 1 3} do_eqp_test 11.10 { SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0'; -} {0 0 0 {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}} +} {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)} + +#------------------------------------------------------------------------- +# Check INDEXED BY works (throws an exception) with partial indexes that +# cannot be used. +do_execsql_test 12.1 { + CREATE TABLE o1(x INTEGER PRIMARY KEY, y, z); + CREATE INDEX p1 ON o1(z); + CREATE INDEX p2 ON o1(y) WHERE z=1; +} +do_catchsql_test 12.2 { + SELECT * FROM o1 INDEXED BY p2 ORDER BY 1; +} {1 {no query solution}} +do_execsql_test 12.3 { + DROP INDEX p1; + DROP INDEX p2; + CREATE INDEX p2 ON o1(y) WHERE z=1; + CREATE INDEX p1 ON o1(z); +} +do_catchsql_test 12.4 { + SELECT * FROM o1 INDEXED BY p2 ORDER BY 1; +} {1 {no query solution}} finish_test diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 85ec0df1f0..e93dcc0cd1 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -380,4 +380,70 @@ do_execsql_test indexexpr1-1300.1 { SELECT a FROM t1300 WHERE substr(b,4)='ess' COLLATE nocase ORDER BY +a; } {3 4} +# Ticket https://sqlite.org/src/tktview/aa98619a +# Assertion fault using an index on a constant +# +do_execsql_test indexexpr1-1400 { + CREATE TABLE t1400(x TEXT); + CREATE INDEX t1400x ON t1400(1); -- Index on a constant + SELECT 1 IN (SELECT 2) FROM t1400; +} {} +do_execsql_test indexexpr1-1410 { + INSERT INTO t1400 VALUES('a'),('b'); + SELECT 1 IN (SELECT 2) FROM t1400; +} {0 0} +do_execsql_test indexexpr1-1420 { + SELECT 1 IN (SELECT 2 UNION ALL SELECT 1) FROM t1400; +} {1 1} +do_execsql_test indexexpr1-1430 { + DROP INDEX t1400x; + CREATE INDEX t1400x ON t1400(abs(15+3)); + SELECT abs(15+3) IN (SELECT 17 UNION ALL SELECT 18) FROM t1; +} {1 1} + +# 2018-01-02 ticket https://sqlite.org/src/info/dc3f932f5a147771 +# A REPLACE into a table that uses an index on an expression causes +# an assertion fault. Problem discovered by OSSFuzz. +# +do_execsql_test indexexpr1-1500 { + CREATE TABLE t1500(a INT PRIMARY KEY, b INT UNIQUE); + CREATE INDEX t1500ab ON t1500(a*b); + INSERT INTO t1500(a,b) VALUES(1,2); + REPLACE INTO t1500(a,b) VALUES(1,3); -- formerly caused assertion fault + SELECT * FROM t1500; +} {1 3} + +# 2018-01-03 OSSFuzz discovers another test case for the same problem +# above. +# +do_execsql_test indexexpr-1510 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a PRIMARY KEY,b UNIQUE); + REPLACE INTO t1 VALUES(2, 1); + REPLACE INTO t1 SELECT 6,1; + CREATE INDEX t1aa ON t1(a-a); + REPLACE INTO t1 SELECT a, randomblob(a) FROM t1 +} {} + +# 2018-01-31 https://www.sqlite.org/src/tktview/343634942dd54ab57b702411 +# When an index on an expression depends on the string representation of +# a numeric table column, trouble can arise since there are multiple +# string that can map to the same numeric value. (Ex: 123, 0123, 000123). +# +do_execsql_test indexexpr-1600 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1 (a INTEGER, b); + CREATE INDEX idx1 ON t1 (lower(a)); + INSERT INTO t1 VALUES('0001234',3); + PRAGMA integrity_check; +} {ok} +do_execsql_test indexexpr-1610 { + INSERT INTO t1 VALUES('1234',0),('001234',2),('01234',1); + SELECT b FROM t1 WHERE lower(a)='1234' ORDER BY +b; +} {0 1 2 3} +do_execsql_test indexexpr-1620 { + SELECT b FROM t1 WHERE lower(a)='01234' ORDER BY +b; +} {} + + finish_test diff --git a/test/indexexpr2.test b/test/indexexpr2.test index c72561f347..3fa3faf87a 100644 --- a/test/indexexpr2.test +++ b/test/indexexpr2.test @@ -40,4 +40,194 @@ do_execsql_test 2.1 { SELECT a+1, quote(a+1) FROM t1 ORDER BY 1; } {2 2 3 3 4 4} +#------------------------------------------------------------------------- +# At one point SQLite was incorrectly using indexes on expressions to +# optimize ORDER BY and GROUP BY clauses even when the collation +# sequences of the query and index did not match (ticket [e20dd54ab0e4]). +# The following tests - 3.* - attempt to verify that this has been fixed. +# + +reset_db +do_execsql_test 3.1.0 { + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); +} {} + +do_eqp_test 3.1.1 { + SELECT b FROM t1 WHERE b IS NOT NULL AND a IS NULL + GROUP BY b COLLATE nocase + ORDER BY b COLLATE nocase; +} {/USE TEMP B-TREE FOR GROUP BY/} + +do_execsql_test 3.2.0 { + CREATE TABLE t2(x); + + INSERT INTO t2 VALUES('.ABC'); + INSERT INTO t2 VALUES('.abcd'); + INSERT INTO t2 VALUES('.defg'); + INSERT INTO t2 VALUES('.DEF'); +} {} + +do_execsql_test 3.2.1 { + SELECT x FROM t2 ORDER BY substr(x, 2) COLLATE nocase; +} { + .ABC .abcd .DEF .defg +} + +do_execsql_test 3.2.2 { + CREATE INDEX i2 ON t2( substr(x, 2) ); + SELECT x FROM t2 ORDER BY substr(x, 2) COLLATE nocase; +} { + .ABC .abcd .DEF .defg +} + +do_execsql_test 3.3.0 { + CREATE TABLE t3(x); +} + +ifcapable json1 { + do_eqp_test 3.3.1 { + SELECT json_extract(x, '$.b') FROM t2 + WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL + GROUP BY json_extract(x, '$.b') COLLATE nocase + ORDER BY json_extract(x, '$.b') COLLATE nocase; + } [string map {"\n " \n} { + QUERY PLAN + |--SCAN TABLE t2 + `--USE TEMP B-TREE FOR GROUP BY + }] + + do_execsql_test 3.3.2 { + CREATE INDEX i3 ON t3(json_extract(x, '$.a'), json_extract(x, '$.b')); + } {} + + do_eqp_test 3.3.3 { + SELECT json_extract(x, '$.b') FROM t3 + WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL + GROUP BY json_extract(x, '$.b') COLLATE nocase + ORDER BY json_extract(x, '$.b') COLLATE nocase; + } [string map {"\n " \n} { + QUERY PLAN + |--SEARCH TABLE t3 USING INDEX i3 (=?) + `--USE TEMP B-TREE FOR GROUP BY + }] +} + +do_execsql_test 3.4.0 { + CREATE TABLE t4(a, b); + INSERT INTO t4 VALUES('.ABC', 1); + INSERT INTO t4 VALUES('.abc', 2); + INSERT INTO t4 VALUES('.ABC', 3); + INSERT INTO t4 VALUES('.abc', 4); +} + +do_execsql_test 3.4.1 { + SELECT * FROM t4 + WHERE substr(a, 2) = 'abc' COLLATE NOCASE + ORDER BY substr(a, 2), b; +} { + .ABC 1 .ABC 3 .abc 2 .abc 4 +} + +do_execsql_test 3.4.2 { + CREATE INDEX i4 ON t4( substr(a, 2) COLLATE NOCASE, b ); + SELECT * FROM t4 + WHERE substr(a, 2) = 'abc' COLLATE NOCASE + ORDER BY substr(a, 2), b; +} { + .ABC 1 .ABC 3 .abc 2 .abc 4 +} + +do_execsql_test 3.4.3 { + DROP INDEX i4; + UPDATE t4 SET a = printf('%s%d',a,b); + SELECT * FROM t4 ORDER BY Substr(a,-2) COLLATE nocase; +} {.ABC1 1 .abc2 2 .ABC3 3 .abc4 4} +do_execsql_test 3.4.4 { + SELECT * FROM t4 ORDER BY Substr(a,-2) COLLATE binary; +} {.ABC1 1 .ABC3 3 .abc2 2 .abc4 4} + +do_execsql_test 3.4.5 { + CREATE INDEX i4 ON t4( Substr(a,-2) COLLATE nocase ); + SELECT * FROM t4 ORDER BY Substr(a,-2) COLLATE nocase; +} {.ABC1 1 .abc2 2 .ABC3 3 .abc4 4} +do_execsql_test 3.4.5eqp { + EXPLAIN QUERY PLAN + SELECT * FROM t4 ORDER BY Substr(a,-2) COLLATE nocase; +} {/SCAN TABLE t4 USING INDEX i4/} +do_execsql_test 3.4.6 { + SELECT * FROM t4 ORDER BY Substr(a,-2) COLLATE binary; +} {.ABC1 1 .ABC3 3 .abc2 2 .abc4 4} + +# 2014-09-15: Verify that UPDATEs of columns not referenced by a +# index on expression do not modify the index. +# +unset -nocomplain cnt +set cnt 0 +proc refcnt {x} { + global cnt + incr cnt + return $x +} +db close +sqlite3 db :memory: +db function refcnt -deterministic refcnt +do_test 4.100 { + db eval { + CREATE TABLE t1(a,b,c,d,e,f); + CREATE INDEX t1abc ON t1(refcnt(a+b+c)); + } + set ::cnt +} {0} +do_test 4.110 { + db eval {INSERT INTO t1 VALUES(1,2,3,4,5,6);} + set ::cnt + # The refcnt() function is invoked once to compute the index value +} {1} +do_test 4.120 { + set ::cnt 0 + db eval {UPDATE t1 SET b=b+1;} + set ::cnt + # The refcnt() function is invoked twice, once to remove the old index + # entry and a second time to insert the new one. +} {2} +do_test 4.130 { + set ::cnt 0 + db eval {UPDATE t1 SET d=d+1;} + set ::cnt + # Refcnt() should not be invoked because that index does not change. +} {0} + +# Additional test cases to show that UPDATE does not modify indexes that +# do not involve unchanged columns. +# +load_static_extension db explain +do_execsql_test 4.200 { + CREATE TABLE t2(a,b,c,d,e,f); + INSERT INTO t2 VALUES(2,3,4,5,6,7); + CREATE INDEX t2abc ON t2(a+b+c); + CREATE INDEX t2cd ON t2(c*d); + CREATE INDEX t2def ON t2(d,e+25*f); + SELECT sqlite_master.name + FROM sqlite_master, explain('UPDATE t2 SET b=b+1') + WHERE explain.opcode LIKE 'Open%' + AND sqlite_master.rootpage=explain.p2 + ORDER BY 1; +} {t2 t2abc} +do_execsql_test 4.210 { + SELECT sqlite_master.name + FROM sqlite_master, explain('UPDATE t2 SET c=c+1') + WHERE explain.opcode LIKE 'Open%' + AND sqlite_master.rootpage=explain.p2 + ORDER BY 1; +} {t2 t2abc t2cd} +do_execsql_test 4.220 { + SELECT sqlite_master.name + FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL') + WHERE explain.opcode LIKE 'Open%' + AND sqlite_master.rootpage=explain.p2 + ORDER BY 1; +} {t2 t2abc t2cd t2def} + + finish_test diff --git a/test/insert.test b/test/insert.test index cb675b90d1..1337105e25 100644 --- a/test/insert.test +++ b/test/insert.test @@ -435,6 +435,19 @@ do_execsql_test insert-12.3 { SELECT * FROM t12c; } {one xyzzy two} +# 2018-06-11. From OSSFuzz. A column cache malfunction in +# the constraint checking on an index of expressions causes +# an assertion fault in a REPLACE. Ticket +# https://www.sqlite.org/src/info/c2432ef9089ee73b +# +do_execsql_test insert-13.1 { + DROP TABLE IF EXISTS t13; + CREATE TABLE t13(a INTEGER PRIMARY KEY,b UNIQUE); + CREATE INDEX t13x1 ON t13(-b=b); + INSERT INTO t13 VALUES(1,5),(6,2); + REPLACE INTO t13 SELECT b,0 FROM t13; + SELECT * FROM t13 ORDER BY +b; +} {2 0 6 2 1 5} integrity_check insert-99.0 diff --git a/test/ioerr.test b/test/ioerr.test index e59647fe50..f42beef5b4 100644 --- a/test/ioerr.test +++ b/test/ioerr.test @@ -172,7 +172,7 @@ ifcapable crashtest&&attach { # These tests can't be run on windows because the windows version of # SQLite holds a mandatory exclusive lock on journal files it has open. # -if {$tcl_platform(platform)!="windows"} { +if {$tcl_platform(platform)!="windows" && ![atomic_batch_write test.db]} { do_ioerr_test ioerr-7 -tclprep { db close sqlite3 db2 test2.db @@ -211,7 +211,7 @@ do_ioerr_test ioerr-8 -ckrefcount true -tclprep { # For test coverage: Cause an IO error whilst reading the master-journal # name from a journal file. -if {$tcl_platform(platform)=="unix"} { +if {$tcl_platform(platform)=="unix" && [atomic_batch_write test.db]==0} { do_ioerr_test ioerr-9 -ckrefcount true -tclprep { execsql { CREATE TABLE t1(a,b,c); diff --git a/test/istrue.test b/test/istrue.test new file mode 100644 index 0000000000..14c013ffc9 --- /dev/null +++ b/test/istrue.test @@ -0,0 +1,161 @@ +# 2018-02-26 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing expressions of the form +# +# x IS TRUE +# x IS FALSE +# x IS NOT TRUE +# x IS NOT FALSE +# +# Tests are also included for the use of TRUE and FALSE as +# literal values. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test istrue-100 { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y BOOLEAN); + INSERT INTO t1 VALUES(1, true),(2, false),(3, null); + SELECT x FROM t1 WHERE y IS TRUE; +} {1} +do_execsql_test istrue-110 { + SELECT x FROM t1 WHERE y IS FALSE; +} {2} +do_execsql_test istrue-120 { + SELECT x FROM t1 WHERE y IS NULL; +} {3} +do_execsql_test istrue-130 { + SELECT x FROM t1 WHERE y IS NOT TRUE; +} {2 3} +do_execsql_test istrue-140 { + SELECT x FROM t1 WHERE y IS NOT FALSE; +} {1 3} +do_execsql_test istrue-150 { + SELECT x FROM t1 WHERE y IS NOT NULL; +} {1 2} +unset -nocomplain X +set X 9 +do_execsql_test istrue-160 { + SELECT x FROM t1 WHERE y IS TRUE OR (8==$X) +} {1} +do_execsql_test istrue-170 { + SELECT x FROM t1 WHERE y IS FALSE OR (8==$X) +} {2} +do_execsql_test istrue-180 { + SELECT x FROM t1 WHERE y IS NULL OR (8==$X); +} {3} +do_execsql_test istrue-190 { + SELECT x FROM t1 WHERE y IS NOT TRUE OR (8==$X); +} {2 3} +do_execsql_test istrue-200 { + SELECT x FROM t1 WHERE y IS NOT FALSE OR (8==$X); +} {1 3} +do_execsql_test istrue-210 { + SELECT x FROM t1 WHERE y IS NOT NULL OR (8==$X); +} {1 2} + +do_execsql_test istrue-300 { + SELECT x, + y IS TRUE, y IS FALSE, y is NULL, + y IS NOT TRUE, y IS NOT FALSE, y IS NOT NULL, '|' + FROM t1 ORDER BY x; +} {1 1 0 0 0 1 1 | 2 0 1 0 1 0 1 | 3 0 0 1 1 1 0 |} + +do_execsql_test istrue-400 { + SELECT x FROM t1 WHERE true; +} {1 2 3} +do_execsql_test istrue-410 { + SELECT x FROM t1 WHERE false; +} {} + +do_execsql_test istrue-500 { + CREATE TABLE t2( + a INTEGER PRIMARY KEY, + b BOOLEAN DEFAULT true, + c BOOLEAN DEFAULT(true), + d BOOLEAN DEFAULT false, + e BOOLEAN DEFAULT(false) + ); + INSERT INTO t2 DEFAULT VALUES; + SELECT * FROM t2; +} {1 1 1 0 0} +do_execsql_test istrue-510 { + DROP TABLE t2; + CREATE TABLE t2( + a INTEGER PRIMARY KEY, + b BOOLEAN DEFAULT(not true), + c BOOLEAN DEFAULT(not false) + ); + INSERT INTO t2(a) VALUES(99); + SELECT * FROM t2; +} {99 0 1} +do_execsql_test istrue-520 { + DROP TABLE t2; + CREATE TABLE t2( + a INTEGER PRIMARY KEY, + b BOOLEAN CHECK(b IS TRUE), + c BOOLEAN CHECK(c IS FALSE), + d BOOLEAN CHECK(d IS NOT TRUE), + e BOOLEAN CHECK(e IS NOT FALSE) + ); + INSERT INTO t2 VALUES(1,true,false,null,null); + SELECT * FROM t2; +} {1 1 0 {} {}} +do_catchsql_test istrue-521 { + INSERT INTO t2 VALUES(2,false,false,null,null); +} {1 {CHECK constraint failed: t2}} +do_catchsql_test istrue-522 { + INSERT INTO t2 VALUES(2,true,true,null,null); +} {1 {CHECK constraint failed: t2}} +do_catchsql_test istrue-523 { + INSERT INTO t2 VALUES(2,true,false,true,null); +} {1 {CHECK constraint failed: t2}} +do_catchsql_test istrue-524 { + INSERT INTO t2 VALUES(2,true,false,null,false); +} {1 {CHECK constraint failed: t2}} + +foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] { + do_execsql_test istrue-600.$tn.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + } + do_test istrue-600.$tn.2 { + set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL] + sqlite3_bind_double $::STMT 1 $val + sqlite3_step $::STMT + sqlite3_reset $::STMT + sqlite3_finalize $::STMT + } {SQLITE_OK} + do_execsql_test istrue-600.$tn.3 { + SELECT x IS TRUE FROM t1; + } [expr {$tn in [list 5 6] ? {1} : {0}}] + do_execsql_test istrue-600.$tn.4 { + SELECT x IS FALSE FROM t1; + } {0} +} + +do_execsql_test istrue-700 { + CREATE TABLE t7( + a INTEGER PRIMARY KEY, + b BOOLEAN DEFAULT false, + c BOOLEAN DEFAULT true + ); + INSERT INTO t7(a) VALUES(1); + INSERT INTO t7(a,b,c) VALUES(2,true,false); + ALTER TABLE t7 ADD COLUMN d BOOLEAN DEFAULT false; + ALTER TABLE t7 ADD COLUMN e BOOLEAN DEFAULT true; + INSERT INTO t7(a,b,c) VALUES(3,true,false); + INSERT INTO t7 VALUES(4,false,true,true,false); + SELECT *,'x' FROM t7 ORDER BY a; +} {1 0 1 0 1 x 2 1 0 0 1 x 3 1 0 0 1 x 4 0 1 1 0 x} + +finish_test diff --git a/test/join.test b/test/join.test index 4df586d8ab..8c6f463bca 100644 --- a/test/join.test +++ b/test/join.test @@ -780,4 +780,68 @@ do_execsql_test join-14.20 { LEFT JOIN t3 AS x3 ON x2.id=x3.c3; } {456 {} {}} +# 2018-03-24. +# E.Pasma discovered that the LEFT JOIN strength reduction optimization +# was misbehaving. The problem turned out to be that the +# sqlite3ExprImpliesNotNull() routine was saying that CASE expressions +# like +# +# CASE WHEN true THEN true ELSE x=0 END +# +# could never be true if x is NULL. The following test cases verify +# that this error has been resolved. +# +db close +sqlite3 db :memory: +do_execsql_test join-15.100 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(3,4); + CREATE TABLE t2(x INT, y INT); + SELECT *, 'x' + FROM t1 LEFT JOIN t2 + WHERE CASE WHEN FALSE THEN a=x ELSE 1 END; +} {1 2 {} {} x 3 4 {} {} x} +do_execsql_test join-15.105 { + SELECT *, 'x' + FROM t1 LEFT JOIN t2 + WHERE a IN (1,3,x,y); +} {1 2 {} {} x 3 4 {} {} x} +do_execsql_test join-15.106 { + SELECT *, 'x' + FROM t1 LEFT JOIN t2 + WHERE NOT ( 'x'='y' AND t2.y=1 ); +} {1 2 {} {} x 3 4 {} {} x} +do_execsql_test join-15.107 { + SELECT *, 'x' + FROM t1 LEFT JOIN t2 + WHERE t2.y IS NOT 'abc' +} {1 2 {} {} x 3 4 {} {} x} +do_execsql_test join-15.110 { + DROP TABLE t1; + DROP TABLE t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t1(a,b) VALUES(1,0),(11,1),(12,1),(13,1),(121,12); + CREATE INDEX t1b ON t1(b); + CREATE TABLE t2(x INTEGER PRIMARY KEY); + INSERT INTO t2(x) VALUES(0),(1); + SELECT a1, a2, a3, a4, a5 + FROM (SELECT a AS a1 FROM t1 WHERE b=0) + JOIN (SELECT x AS x1 FROM t2) + LEFT JOIN (SELECT a AS a2, b AS b2 FROM t1) + ON x1 IS TRUE AND b2=a1 + JOIN (SELECT x AS x2 FROM t2) + ON x2<=CASE WHEN x1 THEN CASE WHEN a2 THEN 1 ELSE -1 END ELSE 0 END + LEFT JOIN (SELECT a AS a3, b AS b3 FROM t1) + ON x2 IS TRUE AND b3=a2 + JOIN (SELECT x AS x3 FROM t2) + ON x3<=CASE WHEN x2 THEN CASE WHEN a3 THEN 1 ELSE -1 END ELSE 0 END + LEFT JOIN (SELECT a AS a4, b AS b4 FROM t1) + ON x3 IS TRUE AND b4=a3 + JOIN (SELECT x AS x4 FROM t2) + ON x4<=CASE WHEN x3 THEN CASE WHEN a4 THEN 1 ELSE -1 END ELSE 0 END + LEFT JOIN (SELECT a AS a5, b AS b5 FROM t1) + ON x4 IS TRUE AND b5=a4 + ORDER BY a1, a2, a3, a4, a5; +} {1 {} {} {} {} 1 11 {} {} {} 1 12 {} {} {} 1 12 121 {} {} 1 13 {} {} {}} + finish_test diff --git a/test/join2.test b/test/join2.test index 9372e770c3..5a70573e0e 100644 --- a/test/join2.test +++ b/test/join2.test @@ -86,10 +86,198 @@ do_execsql_test 2.0 { } do_catchsql_test 2.1 { - SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=c); + SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=coalesce(c,1)); } {1 {ON clause references tables to its right}} do_catchsql_test 2.2 { SELECT * FROM aa JOIN cc ON (a=b) JOIN bb ON (b=c); } {0 {one one one}} +#------------------------------------------------------------------------- +# Test that a problem causing where.c to overlook opportunities to +# omit unnecessary tables from a LEFT JOIN when UNIQUE, NOT NULL column +# that makes this possible happens to be the leftmost in its table. +# +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(k1 INTEGER PRIMARY KEY, k2, k3); + CREATE TABLE t2(k2 INTEGER PRIMARY KEY, v2); + + -- Prior to this problem being fixed, table t3_2 would be omitted from + -- the join queries below, but if t3_1 were used in its place it would + -- not. + CREATE TABLE t3_1(k3 PRIMARY KEY, v3) WITHOUT ROWID; + CREATE TABLE t3_2(v3, k3 PRIMARY KEY) WITHOUT ROWID; +} + +do_eqp_test 3.1 { + SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_1 USING (k3); +} { + QUERY PLAN + |--SCAN TABLE t1 + `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) +} + +do_eqp_test 3.2 { + SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_2 USING (k3); +} { + QUERY PLAN + |--SCAN TABLE t1 + `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) +} + +#------------------------------------------------------------------------- +# Test that tables other than the rightmost can be omitted from a +# LEFT JOIN query. +# +do_execsql_test 4.0 { + CREATE TABLE c1(k INTEGER PRIMARY KEY, v1); + CREATE TABLE c2(k INTEGER PRIMARY KEY, v2); + CREATE TABLE c3(k INTEGER PRIMARY KEY, v3); + + INSERT INTO c1 VALUES(1, 2); + INSERT INTO c2 VALUES(2, 3); + INSERT INTO c3 VALUES(3, 'v3'); + + INSERT INTO c1 VALUES(111, 1112); + INSERT INTO c2 VALUES(112, 1113); + INSERT INTO c3 VALUES(113, 'v1113'); +} +do_execsql_test 4.1.1 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); +} {2 v3 1112 {}} +do_execsql_test 4.1.2 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); +} {2 v3 1112 {}} + +do_execsql_test 4.1.3 { + SELECT DISTINCT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); +} {2 v3 1112 {}} + +do_execsql_test 4.1.4 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); +} {2 v3 2 v3 1112 {} 1112 {}} + +do_eqp_test 4.1.5 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); +} { + QUERY PLAN + |--SCAN TABLE c1 + |--SEARCH TABLE c2 USING INTEGER PRIMARY KEY (rowid=?) + `--SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?) +} +do_eqp_test 4.1.6 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); +} { + QUERY PLAN + |--SCAN TABLE c1 + `--SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?) +} + +do_execsql_test 4.2.0 { + DROP TABLE c1; + DROP TABLE c2; + DROP TABLE c3; + CREATE TABLE c1(k UNIQUE, v1); + CREATE TABLE c2(k UNIQUE, v2); + CREATE TABLE c3(k UNIQUE, v3); + + INSERT INTO c1 VALUES(1, 2); + INSERT INTO c2 VALUES(2, 3); + INSERT INTO c3 VALUES(3, 'v3'); + + INSERT INTO c1 VALUES(111, 1112); + INSERT INTO c2 VALUES(112, 1113); + INSERT INTO c3 VALUES(113, 'v1113'); +} +do_execsql_test 4.2.1 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); +} {2 v3 1112 {}} +do_execsql_test 4.2.2 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); +} {2 v3 1112 {}} + +do_execsql_test 4.2.3 { + SELECT DISTINCT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); +} {2 v3 1112 {}} + +do_execsql_test 4.2.4 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); +} {2 v3 2 v3 1112 {} 1112 {}} + +do_eqp_test 4.2.5 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); +} { + QUERY PLAN + |--SCAN TABLE c1 + |--SEARCH TABLE c2 USING INDEX sqlite_autoindex_c2_1 (k=?) + `--SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?) +} +do_eqp_test 4.2.6 { + SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); +} { + QUERY PLAN + |--SCAN TABLE c1 + `--SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?) +} + +# 2017-11-23 (Thanksgiving day) +# OSSFuzz found an assertion fault in the new LEFT JOIN eliminator code. +# +do_execsql_test 4.3.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(x PRIMARY KEY) WITHOUT ROWID; + CREATE TABLE t2(x); + SELECT a.x + FROM t1 AS a + LEFT JOIN t1 AS b ON (a.x=b.x) + LEFT JOIN t2 AS c ON (a.x=c.x); +} {} +do_execsql_test 4.3.1 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) + INSERT INTO t1(x) SELECT x FROM c; + INSERT INTO t2(x) SELECT x+9 FROM t1; + SELECT a.x, c.x + FROM t1 AS a + LEFT JOIN t1 AS b ON (a.x=b.x) + LEFT JOIN t2 AS c ON (a.x=c.x); +} {1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 10} + +do_execsql_test 5.0 { + CREATE TABLE s1 (a INTEGER PRIMARY KEY); + CREATE TABLE s2 (a INTEGER PRIMARY KEY); + CREATE TABLE s3 (a INTEGER); + CREATE UNIQUE INDEX ndx on s3(a); +} +do_eqp_test 5.1 { + SELECT s1.a FROM s1 left join s2 using (a); +} {SCAN TABLE s1} + +do_eqp_test 5.2 { + SELECT s1.a FROM s1 left join s3 using (a); +} {SCAN TABLE s1} + +do_execsql_test 6.0 { + CREATE TABLE u1(a INTEGER PRIMARY KEY, b, c); + CREATE TABLE u2(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX u1ab ON u1(b, c); +} +do_eqp_test 6.1 { + SELECT u2.* FROM u2 LEFT JOIN u1 ON( u1.a=u2.a AND u1.b=u2.b AND u1.c=u2.c ); +} {SCAN TABLE u2} + +db close +sqlite3 db :memory: +do_execsql_test 7.0 { + CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2),(3,4),(5,6); + CREATE TABLE t2(c,d); INSERT INTO t2 VALUES(2,4),(3,6); + CREATE TABLE t3(x); INSERT INTO t3 VALUES(9); + CREATE VIEW test AS + SELECT *, 'x' + FROM t1 LEFT JOIN (SELECT * FROM t2, t3) ON (c=b AND x=9) + WHERE c IS NULL; + SELECT * FROM test; +} {3 4 {} {} {} x 5 6 {} {} {} x} + + finish_test diff --git a/test/join5.test b/test/join5.test index 352ffd40a6..2df66e7cf1 100644 --- a/test/join5.test +++ b/test/join5.test @@ -164,7 +164,7 @@ do_execsql_test join5-3.3 { # Ticket https://www.sqlite.org/src/tktview/c2a19d81652f40568c770c43 on # 2015-08-20. LEFT JOIN and the push-down optimization. # -do_execsql_test join6-4.1 { +do_execsql_test join5-4.1 { SELECT * FROM ( SELECT 'apple' fruit @@ -178,7 +178,7 @@ do_execsql_test join6-4.1 { SELECT 1 isyellow ) c ON b.fruit='banana'; } {apple apple {} banana banana 1} -do_execsql_test join6-4.2 { +do_execsql_test join5-4.2 { SELECT * FROM (SELECT 'apple' fruit UNION ALL SELECT 'banana') LEFT JOIN (SELECT 1) ON fruit='banana'; @@ -212,4 +212,84 @@ do_execsql_test 5.5 { SELECT * FROM ( SELECT * FROM y1 ) LEFT JOIN y2 ON x } {0 0 1 {}} +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 6.1 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1); + + CREATE TABLE t2(y INTEGER PRIMARY KEY,a,b); + INSERT INTO t2 VALUES(1,2,3); + CREATE INDEX t2a ON t2(a); + CREATE INDEX t2b ON t2(b); +} + +do_execsql_test 6.2 { + SELECT * FROM t1 LEFT JOIN t2 ON a=2 OR b=3 WHERE y IS NULL; +} {} + +do_execsql_test 6.3.1 { + CREATE TABLE t3(x); + INSERT INTO t3 VALUES(1); + CREATE TABLE t4(y, z); + SELECT ifnull(z, '!!!') FROM t3 LEFT JOIN t4 ON (x=y); +} {!!!} + +do_execsql_test 6.3.2 { + CREATE INDEX t4i ON t4(y, ifnull(z, '!!!')); + SELECT ifnull(z, '!!!') FROM t3 LEFT JOIN t4 ON (x=y); +} {!!!} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1); +} + +do_execsql_test 7.1 { + CREATE TABLE t2(x, y, z); + CREATE INDEX t2xy ON t2(x, y); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000 + ) + INSERT INTO t2 SELECT i/10, i, NULL FROM s; + ANALYZE; +} + +do_eqp_test 7.2 { + SELECT * FROM t1 LEFT JOIN t2 ON ( + t2.x = t1.x AND (t2.y=? OR (t2.y=? AND t2.z IS NOT NULL)) + ); +} { + QUERY PLAN + |--SCAN TABLE t1 + `--MULTI-INDEX OR + |--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?) + `--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?) +} + +do_execsql_test 7.3 { + CREATE TABLE t3(x); + + CREATE TABLE t4(x, y, z); + CREATE INDEX t4xy ON t4(x, y); + CREATE INDEX t4xz ON t4(x, z); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000) + INSERT INTO t4 SELECT i/10, i, i FROM s; + + ANALYZE; +} + +do_eqp_test 7.4 { + SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?); +} { + QUERY PLAN + |--SCAN TABLE t3 + `--SEARCH TABLE t4 USING INDEX t4xz (x=?) +} + finish_test diff --git a/test/journal1.test b/test/journal1.test index c89dd2b4c9..bcbafe30f6 100644 --- a/test/journal1.test +++ b/test/journal1.test @@ -22,7 +22,12 @@ source $testdir/tester.tcl # These tests will not work on windows because windows uses # manditory file locking which breaks the copy_file command. # -if {$tcl_platform(platform)=="windows"} { +# Or with atomic_batch_write systems, as journal files are +# not created. +# +if {$tcl_platform(platform)=="windows" + || [atomic_batch_write test.db] +} { finish_test return } diff --git a/test/journal3.test b/test/journal3.test index 939cc27c70..b907352329 100644 --- a/test/journal3.test +++ b/test/journal3.test @@ -20,7 +20,9 @@ source $testdir/malloc_common.tcl # If a connection is required to create a journal file, it creates it with # the same file-system permissions as the database file itself. Test this. # -if {$::tcl_platform(platform) == "unix"} { +if {$::tcl_platform(platform) == "unix" + && [atomic_batch_write test.db]==0 +} { # Changed on 2012-02-13: umask is deliberately ignored for -wal, -journal, # and -shm files. diff --git a/test/jrnlmode.test b/test/jrnlmode.test index 2ba56f2b00..3112f6184e 100644 --- a/test/jrnlmode.test +++ b/test/jrnlmode.test @@ -302,6 +302,7 @@ ifcapable autovacuum&&pragma { # The following test caes, jrnlmode-5.*, test the journal_size_limit # pragma. ifcapable pragma { +if {[atomic_batch_write test.db]==0} { db close forcedelete test.db test2.db test3.db sqlite3 db test.db @@ -454,8 +455,10 @@ ifcapable pragma { list [file exists test.db-journal] [file size test.db-journal] } {1 0} } +} ifcapable pragma { +if {[atomic_batch_write test.db]==0} { # These tests are not run as part of the "journaltest" permutation, # as the test_journal.c layer is incompatible with in-memory journaling. if {[permutation] ne "journaltest"} { @@ -507,6 +510,7 @@ ifcapable pragma { } {0} } } +} ifcapable pragma { catch { db close } diff --git a/test/jrnlmode2.test b/test/jrnlmode2.test index 6ea87d704b..6cc54dc5df 100644 --- a/test/jrnlmode2.test +++ b/test/jrnlmode2.test @@ -18,6 +18,11 @@ ifcapable {!pager_pragmas} { return } +if {[atomic_batch_write test.db]} { + finish_test + return +} + #------------------------------------------------------------------------- # The tests in this file check that the following two bugs (both now fixed) # do not reappear. diff --git a/test/json101.test b/test/json101.test index 7b0292ad03..9a93ee739f 100644 --- a/test/json101.test +++ b/test/json101.test @@ -722,4 +722,97 @@ do_execsql_test json-11.3 { /* } */ } {0} +# 2017-10-27. Demonstrate the ability to access an element from +# a json structure even though the element name constains a "." +# character, by quoting the element name in the path. +# +do_execsql_test json-12.100 { + CREATE TABLE t12(x); + INSERT INTO t12(x) VALUES( + '{"settings": + {"layer2": + {"hapax.legomenon": + {"forceDisplay":true, + "transliterate":true, + "add.footnote":true, + "summary.report":true}, + "dis.legomenon": + {"forceDisplay":true, + "transliterate":false, + "add.footnote":false, + "summary.report":true}, + "tris.legomenon": + {"forceDisplay":true, + "transliterate":false, + "add.footnote":false, + "summary.report":false} + } + } + }'); +} {} +do_execsql_test json-12.110 { + SELECT json_remove(x, '$.settings.layer2."dis.legomenon".forceDisplay') + FROM t12; +} {{{"settings":{"layer2":{"hapax.legomenon":{"forceDisplay":true,"transliterate":true,"add.footnote":true,"summary.report":true},"dis.legomenon":{"transliterate":false,"add.footnote":false,"summary.report":true},"tris.legomenon":{"forceDisplay":true,"transliterate":false,"add.footnote":false,"summary.report":false}}}}}} +do_execsql_test json-12.120 { + SELECT json_extract(x, '$.settings.layer2."tris.legomenon"."summary.report"') + FROM t12; +} {0} + +# 2018-01-26 +# ticket https://www.sqlite.org/src/tktview/80177f0c226ff54f6ddd41 +# Make sure the query planner knows about the arguments to table-valued functions. +# +do_execsql_test json-13.100 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(id, json); + INSERT INTO t1(id,json) VALUES(1,'{"items":[3,5]}'); + CREATE TABLE t2(id, json); + INSERT INTO t2(id,json) VALUES(2,'{"value":2}'); + INSERT INTO t2(id,json) VALUES(3,'{"value":3}'); + INSERT INTO t2(id,json) VALUES(4,'{"value":4}'); + INSERT INTO t2(id,json) VALUES(5,'{"value":5}'); + INSERT INTO t2(id,json) VALUES(6,'{"value":6}'); + SELECT * FROM t1 CROSS JOIN t2 + WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z + WHERE Z.value==t2.id); +} {1 {{"items":[3,5]}} 3 {{"value":3}} 1 {{"items":[3,5]}} 5 {{"value":5}}} +do_execsql_test json-13.110 { + SELECT * FROM t2 CROSS JOIN t1 + WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z + WHERE Z.value==t2.id); +} {3 {{"value":3}} 1 {{"items":[3,5]}} 5 {{"value":5}} 1 {{"items":[3,5]}}} + +# 2018-05-16 +# Incorrect fullkey output from json_each() +# when the input JSON is not an array or object. +# +do_execsql_test json-14.100 { + SELECT fullkey FROM json_each('123'); +} {$} +do_execsql_test json-14.110 { + SELECT fullkey FROM json_each('123.56'); +} {$} +do_execsql_test json-14.120 { + SELECT fullkey FROM json_each('"hello"'); +} {$} +do_execsql_test json-14.130 { + SELECT fullkey FROM json_each('null'); +} {$} +do_execsql_test json-14.140 { + SELECT fullkey FROM json_tree('123'); +} {$} +do_execsql_test json-14.150 { + SELECT fullkey FROM json_tree('123.56'); +} {$} +do_execsql_test json-14.160 { + SELECT fullkey FROM json_tree('"hello"'); +} {$} +do_execsql_test json-14.170 { + SELECT fullkey FROM json_tree('null'); +} {$} + + + finish_test diff --git a/test/json103.test b/test/json103.test index d7d12e3378..35580ce4ea 100644 --- a/test/json103.test +++ b/test/json103.test @@ -75,4 +75,24 @@ do_execsql_test json103-300 { FROM t1; } {{[1,"abc"]} {[{"x":1},{"x":"abc"}]}} +# json_group_array() and json_group_object() work as window functions. +# +ifcapable windowfunc { + do_execsql_test json103-400 { + CREATE TABLE t4(x); + INSERT INTO t4 VALUES + (1), + ('a,b'), + (3), + ('x"y'), + (5), + (6), + (7); + SELECT json_group_array(x) OVER (ROWS 2 PRECEDING) FROM t4; + } {{[1]} {[1,"a,b"]} {[1,"a,b",3]} {["a,b",3,"x\"y"]} {[3,"x\"y",5]} {["x\"y",5,6]} {[5,6,7]}} + do_execsql_test json103-410 { + SELECT json_group_object(rowid, x) OVER (ROWS 2 PRECEDING) FROM t4; + } {{{"1":1}} {{"1":1,"2":"a,b"}} {{"1":1,"2":"a,b","3":3}} {{"2":"a,b","3":3,"4":"x\"y"}} {{"3":3,"4":"x\"y","5":5}} {{"4":"x\"y","5":5,"6":6}} {{"5":5,"6":6,"7":7}}} +} + finish_test diff --git a/test/kvtest.c b/test/kvtest.c index b80adfea09..8c73caf1d7 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -132,7 +132,9 @@ static const char zHelp[] = # define access _access #endif -#include +#if !defined(_MSC_VER) +# include +#endif /* ** The following macros are used to cast pointers to integers and @@ -557,10 +559,10 @@ static int exportMain(int argc, char **argv){ iKey/10000, (iKey/100)%100, iKey%100); } out = fopen(zFN, "wb"); - nWrote = fwrite(pData, 1, nData, out); + nWrote = fwrite(pData, 1, (size_t)nData, out); fclose(out); printf("\r%s ", zTail); fflush(stdout); - if( nWrote!=nData ){ + if( nWrote!=(size_t)nData ){ fatalError("Wrote only %d of %d bytes to %s\n", (int)nWrote, nData, zFN); } @@ -741,16 +743,6 @@ static int display_stats( "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset); - fprintf(out, - "Number of Scratch Allocations Used: %d (max %d)\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset); - fprintf(out, - "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); fprintf(out, "Largest Allocation: %d bytes\n", iHiwtr); @@ -758,10 +750,6 @@ static int display_stats( sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); fprintf(out, "Largest Pcache Allocation: %d bytes\n", iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); - fprintf(out, "Largest Scratch Allocation: %d bytes\n", - iHiwtr); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); diff --git a/test/like.test b/test/like.test index 1702dde714..e5324aee25 100644 --- a/test/like.test +++ b/test/like.test @@ -1048,6 +1048,7 @@ ifcapable !icu { } {1} } +ifcapable !icu { # As of 2017-07-27 (3.21.0) the LIKE optimization works with ESCAPE as # long as the ESCAPE is a single-byte literal. # @@ -1092,8 +1093,6 @@ do_execsql_test like-15.121 { EXPLAIN QUERY PLAN SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/'; } {/SEARCH/} - - - +} finish_test diff --git a/test/like3.test b/test/like3.test index 9280c2c5d2..575faaf104 100644 --- a/test/like3.test +++ b/test/like3.test @@ -112,4 +112,70 @@ do_execsql_test like3-4.2ck { SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x ASC; } {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} +# 2018-09-10 ticket https://www.sqlite.org/src/tktview/c94369cae9b561b1f996 +# The like optimization fails for a column with numeric affinity if +# the pattern '/%' or begins with the escape character. +# +do_execsql_test like3-5.100 { + CREATE TABLE t5a(x INT UNIQUE COLLATE nocase); + INSERT INTO t5a(x) VALUES('/abc'),(123),(-234); + SELECT x FROM t5a WHERE x LIKE '/%'; +} {/abc} +do_eqp_test like3-5.101 { + SELECT x FROM t5a WHERE x LIKE '/%'; +} { + QUERY PLAN + `--SCAN TABLE t5a +} +do_execsql_test like3-5.110 { + SELECT x FROM t5a WHERE x LIKE '/a%'; +} {/abc} +ifcapable !icu { +do_eqp_test like3-5.111 { + SELECT x FROM t5a WHERE x LIKE '/a%'; +} { + QUERY PLAN + `--SEARCH TABLE t5a USING COVERING INDEX sqlite_autoindex_t5a_1 (x>? AND x? AND x10 && $z<100} } {1} do_test lookaside-2.3 { + db eval {SELECT 1} sqlite3_db_config_lookaside db 0 50 50 } {5} ;# SQLITE_BUSY do_test lookaside-2.4 { diff --git a/test/main.test b/test/main.test index 9346cf6ced..13a385b7c4 100644 --- a/test/main.test +++ b/test/main.test @@ -434,7 +434,7 @@ do_test main-3.2.28 { } {0 246} do_test main-3.2.29 { catchsql {select 123/} -} {1 {near "/": syntax error}} +} {1 {incomplete input}} do_test main-3.2.30 { catchsql {select 123--5} } {0 123} @@ -467,7 +467,7 @@ do_test main-3.4 { do_test main-3.5 { set v [catch {execsql {create}} msg] lappend v $msg -} {1 {near "create": syntax error}} +} {1 {incomplete input}} do_test main-3.6 { catchsql {SELECT 'abc' + #9} } {1 {near "#9": syntax error}} diff --git a/test/malloc.test b/test/malloc.test index dbf4699b27..5e82e8028b 100644 --- a/test/malloc.test +++ b/test/malloc.test @@ -329,7 +329,7 @@ ifcapable crashtest&&attach { } } -if {$tcl_platform(platform)!="windows"} { +if {$tcl_platform(platform)!="windows" && [atomic_batch_write test.db]==0} { do_malloc_test 14 -tclprep { catch {db close} sqlite3 db2 test2.db diff --git a/test/malloc3.test b/test/malloc3.test index f4a6c3bbe9..b497ab66e9 100644 --- a/test/malloc3.test +++ b/test/malloc3.test @@ -27,6 +27,17 @@ if {!$MEMDEBUG} { return } +# Do not run these tests if F2FS batch writes are supported. In this case, +# it is possible for a single DML statement in an implicit transaction +# to fail with SQLITE_NOMEM, but for the transaction to still end up +# committed to disk. Which confuses the tests in this module. +# +if {[atomic_batch_write test.db]} { + puts "Skipping malloc3 tests: atomic-batch support" + finish_test + return +} + # Do not run these tests with an in-memory journal. # diff --git a/test/malloc5.test b/test/malloc5.test index bbc9432164..906ac89834 100644 --- a/test/malloc5.test +++ b/test/malloc5.test @@ -174,8 +174,11 @@ do_test malloc5-2.2 { execsql { COMMIT; } - list $nRelease $data -} [list $pgalloc [list 1 2 3 4 5 6]] + value_in_range $::pgalloc $::mrange $nRelease +} [value_in_range $::pgalloc $::mrange] +do_test malloc5-2.2.1 { + set data +} {1 2 3 4 5 6} do_test malloc5-3.1 { # Simple test to show that if two pagers are opened from within this diff --git a/test/mallocK.test b/test/mallocK.test index 45ee7905c3..139644d834 100644 --- a/test/mallocK.test +++ b/test/mallocK.test @@ -121,10 +121,11 @@ do_execsql_test 6.0 { ifcapable stat4 { do_eqp_test 6.1 { SELECT DISTINCT c FROM t3 WHERE b BETWEEN '.xx..' AND '.xxxx'; - } { - 0 0 0 {SEARCH TABLE t3 USING INDEX i3 (ANY(a) AND b>? AND b? AND b [list populate_tree_widget $db $ztest] + $::O(text) tag bind $ztest [list $::O(text) configure -cursor hand2] + $::O(text) tag bind $ztest [list $::O(text) configure -cursor ""] + } + + $::O(text) configure -state disabled +} + +proc sort_tree_compare {iLeft iRight} { + global O + switch -- [expr (int($O(tree_sort)/2))] { + 0 { + set left [$O(tree) item $iLeft -text] + set right [$O(tree) item $iRight -text] + set res [string compare $left $right] + } + 1 { + set left [lindex [$O(tree) item $iLeft -values] 0] + set right [lindex [$O(tree) item $iRight -values] 0] + set res [expr $left - $right] + } + 2 { + set left [lindex [$O(tree) item $iLeft -values] 1] + set right [lindex [$O(tree) item $iRight -values] 1] + set res [expr $left - $right] + } + } + if {$O(tree_sort)&0x01} { + set res [expr -1 * $res] + } + return $res +} + +proc sort_tree {iMode} { + global O + if {$O(tree_sort) == $iMode} { + incr O(tree_sort) + } else { + set O(tree_sort) $iMode + } + set T $O(tree) + set items [$T children {}] + set items [lsort -command sort_tree_compare $items] + for {set ii 0} {$ii < [llength $items]} {incr ii} { + $T move [lindex $items $ii] {} $ii + } +} + +proc trim_frames {stack} { + while {[info exists ::O(ignore.[lindex $stack 0])]} { + set stack [lrange $stack 1 end] + } + return $stack +} + +proc populate_tree_widget {db zTest} { + $::O(tree) delete [$::O(tree) children {}] + + for {set ii 0} {$ii < 15} {incr ii} { + $db eval { + SELECT + sum(ncall) AS calls, + sum(nbyte) AS bytes, + trim_frames(lrange(lstack, 0, $ii)) AS stack + FROM malloc + WHERE (zTest = $zTest OR $zTest = 'TOTAL') AND llength(lstack)>$ii + GROUP BY stack + HAVING stack != '' + } { + set parent_id [lrange $stack 0 end-1] + set frame [lindex $stack end] + set line [$db one {SELECT line FROM frame WHERE frame = $frame}] + set line [lindex [split $line /] end] + set v [list $calls $bytes] + + catch { + $::O(tree) insert $parent_id end -id $stack -text $line -values $v + } + } + } + + set ::O(current) $zTest + populate_index $db +} + + + +set O(tree_sort) 0 + +::ttk::panedwindow .pan -orient horizontal +set O(tree) [scrollable ::ttk::treeview .pan.tree] + +frame .pan.right +set O(text) [scrollable text .pan.right.text] +button .pan.right.index -command {populate_index mddb} -text "Show Index" +pack .pan.right.index -side top -fill x +pack .pan.right.text -fill both -expand true + +$O(text) tag configure highlight -background wheat +$O(text) configure -wrap none -height 35 + +.pan add .pan.tree +.pan add .pan.right + +$O(tree) configure -columns {calls bytes} +$O(tree) heading #0 -text Line -anchor w -command {sort_tree 0} +$O(tree) heading calls -text Calls -anchor w -command {sort_tree 2} +$O(tree) heading bytes -text Bytes -anchor w -command {sort_tree 4} +$O(tree) column #0 -width 150 +$O(tree) column calls -width 100 +$O(tree) column bytes -width 100 + +pack .pan -fill both -expand 1 + +#-------------------------------------------------------------------- +# Open the database containing the malloc data. The user specifies the +# database to use by passing the file-name on the command line. +# +proc open_database {} { + if {[info exists ::BUILTIN]} { + sqlite3 mddb :memory: + mddb eval $::BUILTIN + wm title . $::argv0 + } else { + set zFilename [lindex $::argv 0] + if {$zFilename eq ""} { + set zFilename mallocs.sql + } + set fd [open $zFilename] + set zHdr [read $fd 15] + if {$zHdr eq "SQLite format 3"} { + close $fd + sqlite3 mddb $zFilename + } else { + seek $fd 0 + sqlite3 mddb :memory: + mddb eval [read $fd] + close $fd + } + wm title . $zFilename + } + + mddb function lrange -argcount 3 lrange + mddb function llength -argcount 1 llength + mddb function trim_frames -argcount 1 trim_frames + + mddb eval { + SELECT frame FROM frame + WHERE line LIKE '%malloc.c:%' OR line LIKE '%mem2.c:%' + } { + set ::O(ignore.$frame) 1 + } +} + +open_database +bind $O(tree) <> [list populate_text_widget mddb] + +populate_tree_widget mddb [mddb one {SELECT zTest FROM malloc LIMIT 1}] + diff --git a/test/memdb1.test b/test/memdb1.test new file mode 100644 index 0000000000..771d5e42fa --- /dev/null +++ b/test/memdb1.test @@ -0,0 +1,163 @@ +# 2018-01-02 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is the "memdb" VFS +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix memdb1 +do_not_use_codec + +ifcapable !deserialize { + finish_test + return +} + +# Create a MEMDB and populate it with some dummy data. +# Then extract the database into the $::db1 variable. +# Verify that the size of $::db1 is the same as the size of +# the database. +# +unset -nocomplain db1 +unset -nocomplain sz1 +unset -nocomplain pgsz +do_test 100 { + db eval { + CREATE TABLE t1(a,b); + INSERT INTO t1 VALUES(1,2); + } + set ::pgsz [db one {PRAGMA page_size}] + set ::sz1 [expr {$::pgsz*[db one {PRAGMA page_count}]}] + set ::db1 [db serialize] + expr {[string length $::db1]==$::sz1} +} 1 +set fd [open db1.db wb] +puts -nonewline $fd $db1 +close $fd + +# Create a new MEMDB and initialize it to the content of $::db1 +# Verify that the content is the same. +# +db close +sqlite3 db +db deserialize $db1 +do_execsql_test 110 { + SELECT * FROM t1; +} {1 2} + +# What happens when we try to VACUUM a MEMDB database? +# +do_execsql_test 120 { + PRAGMA auto_vacuum = off; + VACUUM; +} {} +do_execsql_test 130 { + CREATE TABLE t2(x, y); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t2(x, y) SELECT x, randomblob(1000) FROM c; + DROP TABLE t2; + PRAGMA page_count; +} {116} +do_execsql_test 140 { + VACUUM; + PRAGMA page_count; +} {2} + +# Build a largish on-disk database and serialize it. Verify that the +# serialization works. +# +db close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 200 { + CREATE TABLE t3(x, y); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400) + INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c; + PRAGMA quick_check; +} {ok} +set fd [open test.db rb] +unset -nocomplain direct +set direct [read $fd] +close $fd +do_test 210 { + string length [db serialize] +} [string length $direct] +do_test 220 { + db eval {ATTACH ':memory:' AS aux1} + db deserialize aux1 $::direct + db eval { + SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3; + } +} {} +unset -nocomplain direct + +# Do the same with a :memory: database. +# +db close +sqlite3 db :memory: +do_execsql_test 300 { + CREATE TABLE t3(x, y); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400) + INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c; + PRAGMA quick_check; +} {ok} +do_test 310 { + db eval {ATTACH ':memory:' AS aux1} + db deserialize aux1 [db serialize main] + db eval { + SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3; + } +} {} + +# Deserialize an empty database +# +db close +sqlite3 db +db deserialize {} +do_execsql_test 400 { + PRAGMA integrity_check; +} {ok} +do_execsql_test 410 { + CREATE TABLE t4(a,b); + INSERT INTO t4 VALUES('hello','world!'); + PRAGMA integrity_check; + SELECT * FROM t4; +} {ok hello world!} + +# Deserialize something that is not a database. +# +db close +sqlite3 db +do_test 500 { + set rc [catch {db deserialize not-a-database} msg] + lappend rc $msg +} {0 {}} +do_catchsql_test 510 { + PRAGMA integrity_check; +} {1 {file is not a database}} + +# Abuse the serialize and deserialize commands. Make sure errors are caught. +# +do_test 600 { + set rc [catch {db deserialize} msg] + lappend rc $msg +} {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}} +do_test 610 { + set rc [catch {db deserialize a b c} msg] + lappend rc $msg +} {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}} +do_test 620 { + set rc [catch {db serialize a b} msg] + lappend rc $msg +} {1 {wrong # args: should be "db serialize ?DATABASE?"}} + +finish_test diff --git a/test/memsubsys1.test b/test/memsubsys1.test index 36427f9bae..41bc115269 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -16,7 +16,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl sqlite3_reset_auto_extension -# This test assumes that no page-cache or scratch buffers are installed +# This test assumes that no page-cache buffers are installed # by default when a new database connection is opened. As a result, it # will not work with the "memsubsys1" permutation. # @@ -156,12 +156,11 @@ do_test memsubsys1-3.2.5 { set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] } 0 -# Test 4: Activate both PAGECACHE and SCRATCH. +# Test 4: Activate PAGECACHE # db close sqlite3_shutdown sqlite3_config_pagecache [expr 1024+$xtra_size] 50 -sqlite3_config_scratch 6000 2 sqlite3_initialize reset_highwater_marks build_test_db memsubsys1-4 {PRAGMA page_size=1024} @@ -177,144 +176,10 @@ do_test memsubsys1-4.5 { set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] expr {$maxreq<7000} } 1 -do_test memsubsys1-4.6 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 1 - -# Test 5: Activate both PAGECACHE and SCRATCH. But make the page size is -# such that the SCRATCH allocations are too small. -# -db close -sqlite3_shutdown -sqlite3_config_pagecache [expr 4096+$xtra_size] 24 -sqlite3_config_scratch 4000 2 -sqlite3_initialize -reset_highwater_marks -build_test_db memsubsys1-5 {PRAGMA page_size=4096} -#show_memstats -do_test memsubsys1-5.3 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] -} {/^2[34]$/} -do_test memsubsys1-5.4 { - set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] - expr {$maxreq>4096} -} 1 -do_test memsubsys1-5.5 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 0 -do_test memsubsys1-5.6 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] - expr {$s_ovfl>6000} -} 1 - -# Test 6: Activate both PAGECACHE and SCRATCH with a 4k page size. -# Make it so that SCRATCH is large enough -# -db close -sqlite3_shutdown -sqlite3_config_pagecache [expr 4096+$xtra_size] 24 -sqlite3_config_scratch 25300 1 -sqlite3_initialize -reset_highwater_marks -build_test_db memsubsys1-6 {PRAGMA page_size=4096} -#show_memstats -do_test memsubsys1-6.3 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] -} {/^2[34]$/} -#do_test memsubsys1-6.4 { -# set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] -# expr {$maxreq>4096 && $maxreq<=(4096+$xtra_size)} -#} 1 -do_test memsubsys1-6.5 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 1 -do_test memsubsys1-6.6 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] -} 0 - -# Test 7: Activate both PAGECACHE and SCRATCH with a 4k page size. -# Set cache_size small so that no PAGECACHE overflow occurs. Verify -# that maximum allocation size is small. -# -db close -sqlite3_shutdown -sqlite3_config_pagecache [expr 4096+$xtra_size] 24 -sqlite3_config_scratch 25300 1 -sqlite3_initialize -reset_highwater_marks -build_test_db memsubsys1-7 { - PRAGMA page_size=4096; - PRAGMA cache_size=10; - PRAGMA temp_store=memory; -} -#show_memstats -do_test memsubsys1-7.3 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] - expr {$pg_used<24} -} 1 -do_test memsubsys1-7.4 { - set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] -} 0 -do_test memsubsys1-7.5 { - set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] - expr {$maxreq<(4100 + 8200*[nonzero_reserved_bytes])} -} 1 -do_test memsubsys1-7.6 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 1 -do_test memsubsys1-7.7 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] -} 0 - -# Test 8: Disable PAGECACHE. Make available SCRATCH zero. Verify that -# the SCRATCH overflow logic works. -# -db close -sqlite3_shutdown -sqlite3_config_pagecache 0 0 -sqlite3_config_scratch 25000 0 -sqlite3_initialize -reset_highwater_marks -do_test memsubsys1-8.1 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 0 -do_test memsubsys1-8.2 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] -} 0 -do_test memsubsys1-8.3 { - sqlite3 db :memory: - db eval { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - } - expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0} -} 1 -db close -sqlite3_shutdown -sqlite3_config_memstatus 0 -sqlite3_initialize -do_test memsubsys1-8.4 { - sqlite3 db :memory: - db eval { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - SELECT rowid FROM t1; - } -} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16} - db close sqlite3_shutdown sqlite3_config_memstatus 1 -sqlite3_config_scratch 0 0 sqlite3_config_lookaside 100 500 sqlite3_config serialized sqlite3_initialize diff --git a/test/minmax2.test b/test/minmax2.test index da8fec30ce..b6114f2e51 100644 --- a/test/minmax2.test +++ b/test/minmax2.test @@ -383,5 +383,39 @@ do_test minmax2-10.12 { } } {{} {}} +# 2017-10-26. Extend the min/max optimization to indexes on expressions +# +do_execsql_test minmax2-11.100 { + CREATE TABLE t11(a,b,c); + INSERT INTO t11(a,b,c) VALUES(1,10,5),(2,8,11),(3,1,4),(4,20,1),(5,16,4); + CREATE INDEX t11bc ON t11(b+c); + SELECT max(b+c) FROM t11; +} {21} +do_execsql_test minmax2-11.110 { + SELECT a, max(b+c) FROM t11; +} {4 21} +do_test minmax2-11.111 { + db eval {SELECT max(b+c) FROM t11} + db status step +} {0} +do_test minmax2-11.112 { + db eval {SELECT max(c+b) FROM t11} + db status step +} {4} +do_execsql_test minmax2-11.120 { + SELECT a, min(b+c) FROM t11; +} {3 5} +do_test minmax2-11.121 { + db eval {SELECT min(b+c) FROM t11} + db status step +} {0} +do_test minmax2-11.122 { + db eval {SELECT min(c+b) FROM t11} + db status step +} {4} +do_execsql_test minmax2-11.130 { + INSERT INTO t11(a,b,c) VALUES(6,NULL,0),(7,0,NULL); + SELECT a, min(b+c) FROM t11; +} {3 5} finish_test diff --git a/test/misc1.test b/test/misc1.test index be64a8f7a9..05b1b1980f 100644 --- a/test/misc1.test +++ b/test/misc1.test @@ -711,5 +711,35 @@ SELECT-1 UNION SELECT 5 UNION SELECT 0 UNION SElECT*from(SELECT-5) UNION SELECT $group,:conc ap0,1)fro,(select"",:PBAG,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,c,d,c,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d, foreign_keysc,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,c,d,c,a,b,d,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,bb,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,c,d,c,a,b,d,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,MAato_aecSELEC,+?b," "O,"i","a",""b ,5 ))KEY)SELECT*FROM((k()reaC,k,K) eA,k '' )t ,K M); } {1 {'k' is not a function}} +# 2017-09-17 +# +# Sometimes sqlite3ExprListAppend() can be invoked on an ExprList that +# was obtained from sqlite3ExprListDup(). +# +do_execsql_test misc1-26.0 { + DROP TABLE IF EXISTS abc; + CREATE TABLE abc(a, b, c); + SELECT randomblob(min(max(coalesce(EXISTS (SELECT 1 FROM ( SELECT (SELECT 2147483647) NOT IN (SELECT 2147483649 UNION ALL SELECT DISTINCT -1) IN (SELECT 2147483649), 'fault', (SELECT ALL -1 INTERSECT SELECT 'experiments') IN (SELECT ALL 56.1 ORDER BY 'experiments' DESC) FROM (SELECT DISTINCT 2147483648, 'hardware' UNION ALL SELECT -2147483648, 'experiments' ORDER BY 2147483648 LIMIT 1 OFFSET 123456789.1234567899) GROUP BY (SELECT ALL 0 INTERSECT SELECT 'in') IN (SELECT DISTINCT 'experiments' ORDER BY zeroblob(1000) LIMIT 56.1 OFFSET -456) HAVING EXISTS (SELECT 'fault' EXCEPT SELECT DISTINCT 56.1) UNION SELECT 'The', 'The', 2147483649 UNION ALL SELECT DISTINCT 'hardware', 'first', 'experiments' ORDER BY 'hardware' LIMIT 123456789.1234567899 OFFSET -2147483647)) NOT IN (SELECT (SELECT DISTINCT (SELECT 'The') FROM abc ORDER BY EXISTS (SELECT -1 INTERSECT SELECT ALL NULL) ASC) IN (SELECT DISTINCT EXISTS (SELECT ALL 123456789.1234567899 ORDER BY 1 ASC, NULL DESC) FROM sqlite_master INTERSECT SELECT 456)), (SELECT ALL 'injection' UNION ALL SELECT ALL (SELECT DISTINCT 'first' UNION SELECT DISTINCT 'The') FROM (SELECT 456, 'in', 2147483649))),1), 500)), 'first', EXISTS (SELECT DISTINCT 456 FROM abc ORDER BY 'experiments' DESC) FROM abc; +} {} + +# 2017-12-29 +# +# The following behaviors (duplicate column names on an INSERT or UPDATE) +# are undocumented. These tests are added to ensure that historical behavior +# does not change accidentally. +# +# For duplication columns on an INSERT, the first value is used. +# For duplication columns on an UPDATE, the last value is used. +# +do_execsql_test misc1-27.0 { + CREATE TABLE dup1(a,b,c); + INSERT INTO dup1(a,b,c,a,b,c) VALUES(1,2,3,4,5,6); + SELECT a,b,c FROM dup1; +} {1 2 3} +do_execsql_test misc1-27.1 { + UPDATE dup1 SET a=7, b=8, c=9, a=10, b=11, c=12; + SELECT a,b,c FROM dup1; +} {10 11 12} + finish_test diff --git a/test/misc7.test b/test/misc7.test index 8fd5fe7546..93e107beb0 100644 --- a/test/misc7.test +++ b/test/misc7.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix misc7 if {[clang_sanitize_address]==0} { do_test misc7-1-misuse { @@ -42,15 +43,17 @@ do_test misc7-4 { # Try to open a file with a directory where its journal file should be. # -do_test misc7-5 { - delete_file mydir - file mkdir mydir-journal - sqlite3 db2 ./mydir - catchsql { - CREATE TABLE abc(a, b, c); - } db2 -} {1 {unable to open database file}} -db2 close +if {[atomic_batch_write test.db]==0} { + do_test misc7-5 { + delete_file mydir + file mkdir mydir-journal + sqlite3 db2 ./mydir + catchsql { + CREATE TABLE abc(a, b, c); + } db2 + } {1 {unable to open database file}} + db2 close +} #-------------------------------------------------------------------- # The following tests, misc7-6.* test the libraries behaviour when @@ -267,22 +270,27 @@ forcedelete test.db-journal sqlite3 db test.db ifcapable explain { - do_execsql_test misc7-14.1 { + do_execsql_test misc7-14.0 { CREATE TABLE abc(a PRIMARY KEY, b, c); - EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE rowid = 1; + } + do_eqp_test misc7-14.1 { + SELECT * FROM abc AS t2 WHERE rowid = 1; } { - 0 0 0 {SEARCH TABLE abc AS t2 USING INTEGER PRIMARY KEY (rowid=?)} - } - do_execsql_test misc7-14.2 { - EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE a = 1; - } {0 0 0 - {SEARCH TABLE abc AS t2 USING INDEX sqlite_autoindex_abc_1 (a=?)} - } - do_execsql_test misc7-14.3 { - EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 ORDER BY a; - } {0 0 0 - {SCAN TABLE abc AS t2 USING INDEX sqlite_autoindex_abc_1} - } + QUERY PLAN + `--SEARCH TABLE abc AS t2 USING INTEGER PRIMARY KEY (rowid=?) +} + do_eqp_test misc7-14.2 { + SELECT * FROM abc AS t2 WHERE a = 1; +} { + QUERY PLAN + `--SEARCH TABLE abc AS t2 USING INDEX sqlite_autoindex_abc_1 (a=?) +} + do_eqp_test misc7-14.3 { + SELECT * FROM abc AS t2 ORDER BY a; + } { + QUERY PLAN + `--SCAN TABLE abc AS t2 USING INDEX sqlite_autoindex_abc_1 +} } db close @@ -518,8 +526,43 @@ do_test misc7-22.3 { do_test misc7-22.4 { sqlite3_extended_errcode db } SQLITE_READONLY_ROLLBACK - -db close +catch { db close } forcedelete test.db +if {$::tcl_platform(platform)=="unix" + && [atomic_batch_write test.db]==0 +} { + reset_db + do_execsql_test 23.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + } + + do_test 23.1 { + db close + forcedelete tst + file mkdir tst + forcecopy test.db tst/test.db + file attributes tst -permissions r-xr-xr-x + } {} + + sqlite3 db tst/test.db + do_execsql_test 23.2 { + SELECT * FROM t1; + } {1 2} + + do_catchsql_test 23.3 { + INSERT INTO t1 VALUES(3, 4); + } {1 {attempt to write a readonly database}} + + do_test 23.4 { + sqlite3_extended_errcode db + } {SQLITE_READONLY_DIRECTORY} + + do_test 23.5 { + db close + forcedelete tst + } {} +} + finish_test diff --git a/test/misc8.test b/test/misc8.test index b639dd1463..4815ded756 100644 --- a/test/misc8.test +++ b/test/misc8.test @@ -57,6 +57,10 @@ do_catchsql_test misc8-1.7 { ORDER BY rowid; } {1 {abort due to ROLLBACK}} +do_catchsql_test misc8-1.8 { + PRAGMA empty_result_callbacks = 1; + SELECT eval('SELECT * FROM t1 WHERE 1 = 0;'); +} {0 {{}}} reset_db diff --git a/test/mjournal.test b/test/mjournal.test new file mode 100644 index 0000000000..539ebc6946 --- /dev/null +++ b/test/mjournal.test @@ -0,0 +1,163 @@ +# 2017 September 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix mjournal + +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + +# Test that nothing bad happens if a journal file contains a pointer to +# a master journal file that does not have a "-" in the name. At one point +# this was causing a segfault on unix. +# +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); +} + +do_test 1.1 { + forcedelete test.db2journal test.db-journal + + close [open test.db-journal w] + + hexio_write test.db-journal 0 746573742e6462326a6f75726e616c00 + hexio_write test.db-journal 16 00000010 + hexio_write test.db-journal 20 000005e1 + hexio_write test.db-journal 24 d9d505f920a163d7 + + close [open test.db2journal w] + hexio_write test.db2journal 0 abcd +} {2} + +do_execsql_test 1.2 { + SELECT * FROM t1; +} + +do_test 1.3 { + forcedelete test0db2journal test.db-journal + close [open test.db-journal w] + hexio_write test.db-journal 0 74657374306462326a6f75726e616c00 + hexio_write test.db-journal 16 00000010 + hexio_write test.db-journal 20 000005e3 + hexio_write test.db-journal 24 d9d505f920a163d7 + + close [open test0db2journal w] + hexio_write test0db2journal 0 abcd +} {2} + +do_execsql_test 1.4 { + SELECT * FROM t1; +} + +# And now test that nothing bad happens if a master journal contains a +# pointer to a journal file that does not have a "-" in the name. +# +do_test 1.5 { + forcedelete test.db2-master test.db-journal test1 + close [open test.db-journal w] + hexio_write test.db-journal 0 746573742e6462322d6d617374657200 + hexio_write test.db-journal 16 00000010 + hexio_write test.db-journal 20 0000059f + hexio_write test.db-journal 24 d9d505f920a163d7 + + close [open test.db2-master w] + hexio_write test.db2-master 0 746573743100 + + close [open test1 w] + hexio_write test1 0 abcd +} {2} + +do_execsql_test 1.6 { + SELECT * FROM t1; +} + +#------------------------------------------------------------------------- +# Check that master journals are not created if the transaction involves +# multiple temp files. +# +db close +testvfs tvfs +tvfs filter xOpen +tvfs script open_cb +set ::open "" +proc open_cb {method file arglist} { + lappend ::open $file +} + +proc contains_mj {} { + foreach f $::open { + set t [file tail $f] + if {[string match *mj* $t]} { return 1 } + } + return 0 +} + +# Like [do_execsql_test], except that a boolean indicating whether or +# not a master journal file was opened ([file tail] contains "mj") or +# not. Example: +# +# do_hasmj_test 1.0 { SELECT 'a', 'b' } {0 a b} +# +proc do_hasmj_test {tn sql expected} { + set ::open [list] + uplevel [list do_test $tn [subst -nocommands { + set res [execsql "$sql"] + concat [contains_mj] [set res] + }] [list {*}$expected]] +} + +forcedelete test.db +forcedelete test.db2 +forcedelete test.db3 +sqlite3 db test.db -vfs tvfs + +do_execsql_test 2.0 { + ATTACH 'test.db2' AS dbfile; + ATTACH '' AS dbtemp; + ATTACH ':memory:' AS dbmem; + + CREATE TABLE t1(x); + CREATE TABLE dbfile.t2(x); + CREATE TABLE dbtemp.t3(x); + CREATE TABLE dbmem.t4(x); +} + +# Two real files. +do_hasmj_test 2.1 { + BEGIN; + INSERT INTO t1 VALUES(1); + INSERT INTO t2 VALUES(1); + COMMIT; +} {1} + +# One real, one temp file. +do_hasmj_test 2.2 { + BEGIN; + INSERT INTO t1 VALUES(1); + INSERT INTO t3 VALUES(1); + COMMIT; +} {0} + +# One file, one :memory: db. +do_hasmj_test 2.3 { + BEGIN; + INSERT INTO t1 VALUES(1); + INSERT INTO t4 VALUES(1); + COMMIT; +} {0} + +finish_test + diff --git a/test/mmap1.test b/test/mmap1.test index c7c72c0ab2..7dcd1f8a43 100644 --- a/test/mmap1.test +++ b/test/mmap1.test @@ -276,5 +276,48 @@ do_test 5.5 { sqlite3_finalize $::STMT } SQLITE_OK +# +# The "6.*" tests are designed to test the interaction of mmap with file +# truncation (e.g. on Win32) via the VACUUM command. +# +forcedelete test2.db +sqlite3 db2 test2.db +do_test 6.0 { + db2 eval { + PRAGMA auto_vacuum = 0; + PRAGMA page_size = 4096; + } +} {} +do_test 6.1 { + db2 eval { + CREATE TABLE t1(x); + INSERT INTO t1(x) VALUES(randomblob(1000000)); + } +} {} +do_test 6.2 { + db2 eval { + PRAGMA mmap_size = 1048576; + } +} {1048576} +do_test 6.3 { + expr {[file size test2.db] > 1000000} +} {1} +do_test 6.4 { + db2 eval { + DELETE FROM t1; + } +} {} +do_test 6.5 { + expr {[file size test2.db] > 1000000} +} {1} +do_test 6.6 { + db2 eval { + VACUUM; + } +} {} +do_test 6.7 { + expr {[file size test2.db] < 1000000} +} {1} +db2 close finish_test diff --git a/test/mmapwarm.test b/test/mmapwarm.test new file mode 100644 index 0000000000..b077047ebc --- /dev/null +++ b/test/mmapwarm.test @@ -0,0 +1,81 @@ +# 20 September 18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + + +if 0 { + db close + sqlite3_shutdown + proc msg {args} { puts $args } + test_sqlite3_log msg + sqlite3 db test.db +} + +set testprefix mmapwarm + + +do_execsql_test 1.0 { + PRAGMA auto_vacuum = 0; + CREATE TABLE t1(x, y); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500 + ) + INSERT INTO t1 SELECT randomblob(400), randomblob(500) FROM s; + PRAGMA page_count; +} {507} +db close + +do_test 1.1 { + sqlite3 db test.db + db eval {PRAGMA mmap_size = 1000000} + sqlite3_mmap_warm db +} {SQLITE_OK} + +do_test 1.2 { + db close + sqlite3 db test.db + db eval {PRAGMA mmap_size = 1000000} + sqlite3_mmap_warm db "main" +} {SQLITE_OK} + +do_test 1.3 { + sqlite3 db test.db + sqlite3_mmap_warm db +} {SQLITE_OK} + +do_test 1.4 { + db close + sqlite3 db test.db + sqlite3_mmap_warm db "main" +} {SQLITE_OK} + +do_test 2.0 { + db close + sqlite3 db test.db + db eval BEGIN + sqlite3_mmap_warm db "main" +} {SQLITE_MISUSE} + +do_faultsim_test 3 -faults oom* -prep { + sqlite3 db test.db + sqlite3_db_config_lookaside db 0 0 0 + db eval { PRAGMA mmap_size = 1000000 } + db eval { SELECT * FROM sqlite_master } +} -body { + sqlite3_mmap_warm db "main" +} -test { + faultsim_test_result {0 SQLITE_OK} {0 SQLITE_NOMEM} +} + +finish_test diff --git a/test/nan.test b/test/nan.test index 27fa04a351..615a4ad227 100644 --- a/test/nan.test +++ b/test/nan.test @@ -366,8 +366,10 @@ do_realnum_test nan-4.35 { } } {0.0 real} - - - +do_realnum_test nan-4.40 { + db eval { + SELECT cast('-1e999' AS real); + } +} {-inf} finish_test diff --git a/test/nockpt.test b/test/nockpt.test index bd3953f1ee..4cc61d11e1 100644 --- a/test/nockpt.test +++ b/test/nockpt.test @@ -61,6 +61,87 @@ do_test 1.14 { sqlite3_db_config db NO_CKPT_ON_CLOSE 1 } {1} do_execsql_test 1.14 { PRAGMA main.journal_mode = delete } {delete} do_test 1.15 { file exists test.db-wal } {0} +if {$::tcl_platform(platform)!="windows"} { +#------------------------------------------------------------------------- +# Test an unusual scenario: +# +# 1. A wal mode db is opened and written. Then sqlite3_close_v2() used +# to close the db handle while there is still an unfinalized +# statement (so the db handle stays open). +# +# 2. The db, wal and *-shm files are deleted from the file system. +# +# 3. Another connection creates a new wal mode db at the same file-system +# location as the previous one. +# +# 4. The statement left unfinalized in (1) is finalized. +# +# The test is to ensure that the connection left open in step (1) does +# not try to delete the wal file from the file-system as part of step +# 4. +# +reset_db +db close + +# Open a connection on a wal database. Write to it a bit. Then prepare +# a statement and call sqlite3_close_v2() (so that the statement handle +# holds the db connection open). +# +set ::db1 [sqlite3_open_v2 test.db SQLITE_OPEN_READWRITE ""] +do_test 2.0 { + lindex [ + sqlite3_exec $::db1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x PRIMARY KEY, y UNIQUE, z); + INSERT INTO t1 VALUES(1, 2, 3); + PRAGMA wal_checkpoint; + }] 0 +} {0} +set ::stmt [sqlite3_prepare $::db1 "SELECT * FROM t1" -1 dummy] +sqlite3_close_v2 $::db1 + +# Delete the database, wal and shm files. +# +forcedelete test.db test.db-wal test.db-shm + +# Open and populate a new database file at the same file-system location +# as the one just deleted. Contrive a partial checkpoint on it. +# +sqlite3 db test.db +sqlite3 db2 test.db +do_execsql_test 2.1 { + PRAGMA auto_vacuum=OFF; + PRAGMA journal_mode = wal; + CREATE TABLE y1(a PRIMARY KEY, b UNIQUE, c); + INSERT INTO y1 VALUES('a', 'b', 'c'); + INSERT INTO y1 VALUES('d', 'e', 'f'); +} {wal} +do_execsql_test -db db2 2.2 { + BEGIN; + SELECT * FROM y1; +} {a b c d e f} +do_execsql_test 2.3 { + UPDATE y1 SET c='g' WHERE a='d'; + PRAGMA wal_checkpoint; +} {0 11 10} +do_execsql_test -db db2 2.4 { + COMMIT +} + +# Finalize the statement handle, causing the first connection to be +# closed. Test that this has not corrupted the database file by +# deleting the new wal file from the file-system. If it has, this +# test should fail with an IO or corruption error. +# +do_test 2.5 { + sqlite3_finalize $::stmt + sqlite3 db3 test.db + execsql { + PRAGMA integrity_check; + SELECT * FROM y1; + } db3 +} {ok a b c d e g} +} finish_test diff --git a/test/normalize.test b/test/normalize.test new file mode 100644 index 0000000000..9e3ec9c967 --- /dev/null +++ b/test/normalize.test @@ -0,0 +1,75 @@ +# 2018-01-08 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Tests for the sqlite3_normalize() extension function. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix normalize + +foreach {tnum sql norm} { + 100 + {SELECT * FROM t1 WHERE a IN (1) AND b=51.42} + {select*from t1 where a in(?,?,?)and b=?;} + + 110 + {SELECT a, b+15, c FROM t1 WHERE d NOT IN (SELECT x FROM t2);} + {select a,b+?,c from t1 where d not in(select x from t2);} + + 120 + { SELECT NULL, b FROM t1 -- comment text + WHERE d IN (WITH t(a) AS (VALUES(5)) /* CTE */ + SELECT a FROM t) + OR e='hello'; + } + {select?,b from t1 where d in(with t(a)as(values(?))select a from t)or e=?;} + + 121 + {/*Initial comment*/ + -- another comment line + SELECT NULL /* comment */ , b FROM t1 -- comment text + WHERE d IN (WITH t(a) AS (VALUES(5)) /* CTE */ + SELECT a FROM t) + OR e='hello'; + } + {select?,b from t1 where d in(with t(a)as(values(?))select a from t)or e=?;} + + 130 + {/* Query containing parameters */ + SELECT x,$::abc(15),y,@abc,z,?99,w FROM t1 /* Trailing comment */} + {select x,?,y,?,z,?,w from t1;} + + 140 + {/* Long list on the RHS of IN */ + SELECT 15 IN (1,2,3,(SELECT * FROM t1),'xyz',x'abcd',22*(x+5),null);} + {select?in(?,?,?);} + + 150 + {SELECT x'abc'; -- illegal token} + {} + + 160 + {SELECT a,NULL,b FROM t1 WHERE c IS NOT NULL or D is null or e=5} + {select a,?,b from t1 where c is not null or d is null or e=?;} + + 170 + {/* IN list exactly 5 bytes long */ + SELECT * FROM t1 WHERE x IN (1,2,3);} + {select*from t1 where x in(?,?,?);} + 180 + { } + {} +} { + do_test $tnum [list sqlite3_normalize $sql] $norm +} + +finish_test diff --git a/test/notnull.test b/test/notnull.test index 23fd33d4ba..32d95eaf24 100644 --- a/test/notnull.test +++ b/test/notnull.test @@ -561,4 +561,49 @@ do_test notnull-5.5 { execsql { SELECT * FROM t1 } } {1 2} +#------------------------------------------------------------------------- +# Check that UNIQUE NOT NULL indexes are always recognized as such. +# +proc uses_op_next {sql} { + db eval "EXPLAIN $sql" a { + if {$a(opcode)=="Next"} { return 1 } + } + return 0 +} + +proc do_uses_op_next_test {tn sql res} { + uplevel [list do_test $tn [list uses_op_next $sql] $res] +} + +reset_db +do_execsql_test notnull-6.0 { + CREATE TABLE t1(a UNIQUE); + CREATE TABLE t2(a NOT NULL UNIQUE); + CREATE TABLE t3(a UNIQUE NOT NULL); + CREATE TABLE t4(a NOT NULL); + CREATE UNIQUE INDEX t4a ON t4(a); + + CREATE TABLE t5(a PRIMARY KEY); + CREATE TABLE t6(a PRIMARY KEY NOT NULL); + CREATE TABLE t7(a NOT NULL PRIMARY KEY); + CREATE TABLE t8(a PRIMARY KEY) WITHOUT ROWID; + + CREATE TABLE t9(a PRIMARY KEY UNIQUE NOT NULL); + CREATE TABLE t10(a UNIQUE PRIMARY KEY NOT NULL); +} + +do_uses_op_next_test notnull-6.1 "SELECT * FROM t1 WHERE a IS ?" 1 +do_uses_op_next_test notnull-6.2 "SELECT * FROM t2 WHERE a IS ?" 0 +do_uses_op_next_test notnull-6.3 "SELECT * FROM t3 WHERE a IS ?" 0 +do_uses_op_next_test notnull-6.4 "SELECT * FROM t4 WHERE a IS ?" 0 + +do_uses_op_next_test notnull-6.5 "SELECT * FROM t5 WHERE a IS ?" 1 +do_uses_op_next_test notnull-6.6 "SELECT * FROM t6 WHERE a IS ?" 0 +do_uses_op_next_test notnull-6.7 "SELECT * FROM t7 WHERE a IS ?" 0 +do_uses_op_next_test notnull-6.8 "SELECT * FROM t8 WHERE a IS ?" 0 + +do_uses_op_next_test notnull-6.9 "SELECT * FROM t8 WHERE a IS ?" 0 +do_uses_op_next_test notnull-6.10 "SELECT * FROM t8 WHERE a IS ?" 0 + finish_test + diff --git a/test/optfuzz-db01.c b/test/optfuzz-db01.c new file mode 100644 index 0000000000..1cd3867e18 --- /dev/null +++ b/test/optfuzz-db01.c @@ -0,0 +1,948 @@ +/* content of file testdb01.db */ +unsigned char data001[] = { + 83, 81, 76,105,116,101, 32,102,111,114,109, 97,116, 32, 51, 0, 2, 0, 1, + 1, 0, 64, 32, 32, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 31, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 46, 32,152, 5, 0, 0, 0, 7, 1,221, 0, 0, 0, 0, 35, 1,251, + 1,246, 1,241, 1,236, 1,231, 1,226, 1,221, 84, 4, 7, 23, 17, 17, 1, + 129, 19,116, 97, 98,108,101,116, 52,116, 52, 5, 67, 82, 69, 65, 84, 69, 32, + 84, 65, 66, 76, 69, 32,116, 52, 40, 97, 32, 73, 78, 84, 32, 85, 78, 73, 81, + 85, 69, 32, 78, 79, 84, 32, 78, 85, 76, 76, 44, 32, 98, 32, 73, 78, 84, 32, + 85, 78, 73, 81, 85, 69, 32, 78, 79, 84, 32, 78, 85, 76, 76, 44, 99, 44,100, + 44,101, 41, 35, 6, 6, 23, 55, 17, 1, 0,105,110,100,101,120,115,113,108, + 105,116,101, 95, 97,117,116,111,105,110,100,101,120, 95,116, 52, 95, 50,116, + 52, 7, 35, 5, 6, 23, 55, 17, 1, 0,105,110,100,101,120,115,113,108,105, + 116,101, 95, 97,117,116,111,105,110,100,101,120, 95,116, 52, 95, 49,116, 52, + 6, 42, 3, 6, 23, 17, 17, 1, 65,116, 97, 98,108,101,116, 51,116, 51, 4, + 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 51, 40, 97, 44, 98, + 44, 99, 44,100, 44,101, 41, 95, 2, 7, 23, 17, 17, 1,129, 41,116, 97, 98, + 108,101,116, 50,116, 50, 3, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, + 32,116, 50, 40, 97, 32, 73, 78, 84, 44, 32, 98, 32, 73, 78, 84, 44, 32, 99, + 32, 73, 78, 84, 44,100, 32, 73, 78, 84, 44,101, 32, 73, 78, 84, 44, 80, 82, + 73, 77, 65, 82, 89, 32, 75, 69, 89, 40, 98, 44, 97, 41, 41, 87, 73, 84, 72, + 79, 85, 84, 32, 82, 79, 87, 73, 68, 83, 1, 7, 23, 17, 17, 1,129, 17,116, + 97, 98,108,101,116, 49,116, 49, 2, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, + 76, 69, 32,116, 49, 40, 97, 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, + 77, 65, 0, 0, 0, 34, 32, 0, 0, 0, 33, 29, 0, 0, 0, 32, 26, 0, 0, + 0, 31, 23, 0, 0, 0, 30, 19, 0, 0, 0, 11, 14, 0, 0, 0, 9, 7, 5, + 0, 0, 0, 1, 1,251, 0, 0, 0, 0, 16, 1,251, 1,195, 1,180, 1,166, + 1,151, 1,136, 1,121, 1,105, 1, 91, 1, 76, 1, 61, 1, 46, 1, 29, 1, + 14, 0,252, 0,238, 0,224, 0,209, 0,194, 0,177, 0,157, 0,143, 0,128, + 0,110, 0, 94, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 14, 28, 6, 0, 1, 1, 1, 23, 17, 67, 31,119,111,114,107,115, 14, 27, + 6, 0, 1, 1, 1, 23, 22, 71, 3, 97,110,103,101,108, 16, 26, 6, 0, 1, + 1, 1, 27, 40, 98, 17,109,111,114,110,105,110,103, 13, 25, 6, 0, 1, 1, + 1, 21, 10, 7, 19,103,111,110,101, 12, 24, 6, 0, 1, 1, 9, 21, 43, 46, + 119, 97,121,115, 18, 23, 6, 0, 1, 1, 1, 31, 6, 37, 31,115, 97, 99,114, + 105,102,105, 99,101, 15, 22, 6, 0, 1, 1, 1, 25, 45, 71, 28,116,104,111, + 117,103,104, 13, 21, 6, 0, 1, 1, 1, 21, 22, 92, 18,115,111,109,101, 13, + 20, 6, 0, 9, 1, 1, 23, 2, 45, 97, 98,111,118,101, 12, 19, 6, 0, 1, + 1, 8, 21, 4, 58,119, 97,121,115, 12, 18, 6, 0, 1, 1, 1, 19, 44, 19, + 43,119, 97,114, 16, 17, 6, 0, 1, 1, 1, 27, 29, 74, 36, 98,101,116,119, + 101,101,110, 13, 16, 6, 0, 1, 1, 1, 21, 44, 52, 19,112,111,111,114, 15, + 15, 6, 0, 1, 1, 1, 25, 6, 3, 11,116,101,109,112,108,101, 13, 14, 6, + 0, 1, 1, 1, 21, 35, 48, 27,100,105,101,100, 13, 13, 6, 0, 1, 1, 1, + 21, 4, 21, 39,100,111,116,104, 13, 12, 6, 0, 1, 1, 1, 21, 4, 38, 36, + 115,101,110,100, 12, 11, 6, 0, 1, 1, 1, 19, 13, 48, 22,115,105,120, 14, + 10, 6, 0, 1, 1, 1, 23, 41, 89, 14,115,101,114,118,101, 13, 9, 6, 0, + 8, 1, 1, 23, 16, 50, 98,101,103, 97,116, 13, 8, 6, 0, 1, 1, 1, 21, + 42, 49, 34,115,101,110,100, 13, 7, 6, 0, 1, 1, 1, 21, 21, 91, 38,110, + 101, 97,114, 12, 6, 6, 0, 1, 1, 1, 19, 2, 37, 11, 99, 97,110, 13, 5, + 6, 0, 1, 1, 1, 21, 25, 27, 28,103,111,110,101, 13, 4, 6, 0, 1, 1, + 1, 21, 41, 32, 35,110,101, 97,114, 14, 3, 6, 0, 1, 1, 1, 23, 32, 24, + 26,115,101,114,118,101, 13, 2, 6, 0, 1, 1, 1, 21, 45, 14, 39,115, 97, + 118,101, 13, 1, 6, 0, 1, 1, 1, 21, 40, 68, 0, 0, 0, 15, 28, 2, 0, + 0, 0, 1, 1,238, 0, 0, 0, 0, 22, 1,238, 1,197, 1,181, 1,166, 1, + 151, 1,137, 1,121, 1,104, 1, 84, 1, 73, 1, 59, 1, 41, 1, 26, 1, 11, + 0,253, 0,238, 0,223, 0,207, 0,191, 0,175, 0,159, 0,144, 0,129, 0, + 113, 0, 97, 0, 82, 0, 68, 0, 0, 13, 6, 1, 1, 1, 1, 19, 26, 34, 15, + 20, 97,114,107, 14, 6, 1, 1, 1, 1, 21, 25, 5, 27, 28,103,111,110,101, + 15, 6, 1, 1, 1, 1, 23, 22, 47, 16, 40, 97,110,103,101,114, 15, 6, 1, + 1, 1, 1, 23, 22, 27, 71, 3, 97,110,103,101,108, 14, 6, 1, 1, 1, 1, + 21, 22, 21, 92, 18,115,111,109,101, 14, 6, 1, 1, 1, 1, 21, 21, 7, 91, + 38,110,101, 97,114, 15, 6, 1, 1, 1, 1, 23, 20, 42, 18, 5, 98,101,103, + 97,116, 15, 6, 1, 1, 1, 1, 23, 17, 37, 66, 18,100,119,101,108,116, 15, + 6, 1, 1, 1, 1, 23, 17, 28, 67, 31,119,111,114,107,115, 15, 6, 1, 1, + 1, 8, 25, 16, 32, 7,112,108, 97, 99,101,115, 14, 6, 1, 1, 1, 1, 21, + 16, 30, 81, 25,119, 97,108,107, 14, 6, 1, 1, 1, 1, 21, 14, 40, 30, 26, + 115,101,110,100, 13, 6, 1, 1, 1, 1, 19, 13, 11, 48, 22,115,105,120, 14, + 6, 1, 1, 1, 1, 21, 10, 38, 97, 34,115,104,101,119, 14, 6, 1, 1, 1, + 1, 21, 10, 25, 7, 19,103,111,110,101, 17, 6, 1, 1, 1, 1, 27, 9, 50, + 92, 29,116,104,101,114,101,105,110, 13, 6, 1, 1, 1, 1, 19, 9, 49, 51, + 38,111,105,108, 10, 6, 1, 1, 1, 1, 0, 7, 33, 72, 31, 19, 6, 1, 1, + 1, 1, 31, 6, 23, 37, 31,115, 97, 99,114,105,102,105, 99,101, 16, 6, 1, + 1, 1, 1, 25, 6, 15, 3, 11,116,101,109,112,108,101, 15, 6, 1, 1, 1, + 1, 23, 5, 43, 23, 41, 98,101,103, 97,116, 13, 6, 1, 1, 1, 8, 21, 4, + 19, 58,119, 97,121,115, 14, 6, 1, 1, 1, 1, 21, 4, 13, 21, 39,100,111, + 116,104, 14, 6, 1, 1, 1, 1, 21, 4, 12, 38, 36,115,101,110,100, 15, 6, + 1, 1, 1, 1, 23, 3, 39, 21, 45, 98,101,103, 97,116, 13, 6, 1, 1, 1, + 1, 19, 2, 6, 37, 11, 99, 97,110, 14, 6, 9, 1, 1, 1, 23, 20, 2, 45, + 97, 98,111,118,101, 14, 6, 8, 1, 1, 1, 23, 36, 52, 17, 99,104, 0, 0, + 0, 21, 13, 6, 1, 1, 1, 1, 19, 26, 34, 15, 20, 97,114,107, 13, 0, 0, + 0, 35, 0, 92, 0, 1,244, 1,232, 1,216, 1,204, 1,186, 1,171, 1,160, + 1,149, 1,138, 1,128, 1,117, 1,106, 1, 92, 1, 76, 1, 65, 1, 49, 1, + 32, 1, 21, 1, 10, 0,255, 0,241, 0,225, 0,214, 0,203, 0,192, 0,180, + 0,168, 0,156, 0,144, 0,132, 0,124, 0,116, 0,108, 0,100, 0, 92, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 35, 6, 0, 0, 0, + 0, 0, 6, 34, 6, 0, 0, 0, 0, 0, 6, 33, 6, 0, 0, 0, 0, 0, 6, + 32, 6, 0, 0, 0, 0, 0, 6, 31, 6, 0, 0, 0, 0, 0, 10, 30, 6, 1, + 1, 1, 1, 0, 48, 37, 93, 7, 10, 29, 6, 1, 1, 1, 1, 0, 28, 17, 67, + 31, 10, 28, 6, 1, 1, 1, 1, 0, 22, 45, 71, 28, 10, 27, 6, 1, 1, 1, + 1, 0, 12, 4, 38, 36, 10, 26, 6, 1, 1, 1, 1, 0, 49, 9, 51, 38, 9, + 25, 6, 1, 1, 1, 0, 0, 17, 29, 74, 9, 24, 6, 1, 1, 1, 0, 0, 47, + 22, 16, 9, 23, 6, 1, 1, 1, 0, 0, 32, 16, 7, 14, 22, 6, 1, 1, 1, + 0, 23, 42, 20, 18, 98,101,103, 97,116, 12, 21, 6, 1, 1, 1, 0, 19, 34, + 26, 15, 97,114,107, 9, 20, 6, 1, 1, 0, 1, 0, 49, 9, 38, 9, 19, 6, + 1, 1, 0, 1, 0, 44, 48, 9, 9, 18, 6, 1, 1, 0, 1, 0, 21, 22, 18, + 15, 17, 6, 1, 1, 0, 1, 25, 35, 38, 22, 99,117, 98,105,116,115, 14, 16, + 6, 1, 1, 0, 1, 23, 37, 17, 18,100,119,101,108,116, 9, 15, 6, 1, 0, + 1, 1, 0, 49, 51, 38, 14, 14, 6, 1, 0, 1, 1, 23, 10, 89, 14,115,101, + 114,118,101, 12, 13, 6, 9, 0, 1, 1, 21, 68, 32,100,111,116,104, 9, 12, + 6, 1, 0, 1, 1, 0, 47, 16, 40, 9, 11, 6, 1, 0, 1, 1, 0, 25, 7, + 19, 8, 10, 6, 0, 1, 1, 8, 0, 16, 7, 9, 9, 6, 0, 1, 1, 1, 0, + 16, 81, 25, 9, 8, 6, 0, 1, 1, 1, 0, 7, 72, 31, 9, 7, 6, 0, 1, + 1, 1, 0, 6, 37, 31, 13, 6, 6, 0, 1, 1, 1, 21, 21, 91, 38,110,101, + 97,114, 16, 5, 6, 1, 1, 1, 1, 25, 15, 6, 3, 11,116,101,109,112,108, + 101, 10, 4, 6, 1, 1, 1, 1, 0, 21, 22, 92, 18, 14, 3, 6, 1, 1, 1, + 1, 21, 4, 41, 32, 35,110,101, 97,114, 10, 2, 6, 1, 1, 1, 1, 0, 46, + 28, 88, 22, 10, 1, 6, 1, 1, 1, 1, 0, 17, 29, 74, 36, 13, 0, 0, 0, + 15, 1, 71, 0, 1,243, 1,230, 1,217, 1,204, 1,191, 1,179, 1,167, 1, + 155, 1,143, 1,131, 1,119, 1,107, 1, 95, 1, 83, 1, 71, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 15, 6, 1, 1, 1, 1, 0, 48, 37, 93, 7, 10, 14, 6, 1, 1, 1, 1, + 0, 22, 45, 71, 28, 10, 13, 6, 1, 1, 1, 1, 0, 12, 4, 38, 36, 10, 12, + 6, 1, 1, 1, 0, 1, 32, 16, 7, 79, 10, 11, 6, 1, 1, 1, 0, 1, 42, + 20, 18, 19, 10, 10, 6, 1, 1, 1, 0, 1, 34, 26, 15, 13, 10, 9, 6, 1, + 1, 0, 1, 1, 49, 9, 38, 97, 10, 8, 6, 1, 1, 0, 1, 1, 44, 48, 9, + 90, 10, 7, 6, 1, 1, 0, 1, 1, 35, 38, 22, 33, 10, 6, 6, 1, 1, 0, + 1, 1, 37, 17, 18, 18, 11, 5, 6, 1, 1, 1, 1, 1, 15, 6, 3, 11, 43, + 11, 4, 6, 1, 1, 1, 1, 1, 21, 22, 92, 18, 62, 11, 3, 6, 1, 1, 1, + 1, 1, 4, 41, 32, 35, 36, 11, 2, 6, 1, 1, 1, 1, 1, 46, 28, 88, 22, + 77, 11, 1, 6, 1, 1, 1, 1, 1, 17, 29, 74, 36, 61, 10, 0, 0, 0, 15, + 1,167, 0, 1,250, 1,244, 1,238, 1,233, 1,227, 1,221, 1,215, 1,209, + 1,203, 1,197, 1,191, 1,185, 1,179, 1,173, 1,167, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 3, 1, 1, 49, 9, 5, 3, 1, 1, 48, 15, 5, 3, 1, 1, 46, 2, 5, + 3, 1, 1, 44, 8, 5, 3, 1, 1, 42, 11, 5, 3, 1, 1, 37, 6, 5, 3, + 1, 1, 35, 7, 5, 3, 1, 1, 34, 10, 5, 3, 1, 1, 32, 12, 5, 3, 1, + 1, 22, 14, 5, 3, 1, 1, 21, 4, 4, 3, 1, 9, 17, 5, 3, 1, 1, 15, + 5, 5, 3, 1, 1, 12, 13, 5, 3, 1, 1, 4, 3, 10, 0, 0, 0, 15, 1, + 167, 0, 1,250, 1,244, 1,238, 1,232, 1,226, 1,220, 1,214, 1,208, 1, + 202, 1,197, 1,191, 1,185, 1,179, 1,173, 1,167, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 3, 1, 1, 48, 8, 5, 3, 1, 1, 45, 14, 5, 3, 1, 1, 41, 3, 5, 3, + 1, 1, 38, 7, 5, 3, 1, 1, 37, 15, 4, 3, 1, 9, 29, 5, 3, 1, 1, + 28, 2, 5, 3, 1, 1, 26, 10, 5, 3, 1, 1, 22, 4, 5, 3, 1, 1, 20, + 11, 5, 3, 1, 1, 17, 6, 5, 3, 1, 1, 16, 12, 5, 3, 1, 1, 9, 9, + 5, 3, 1, 1, 6, 5, 5, 3, 1, 1, 4, 13, 5, 0, 0, 0, 2, 1,246, + 0, 0, 0, 0, 27, 1,251, 1,246, 1,168, 1,148, 1,130, 1,107, 1, 86, + 1, 65, 1, 44, 1, 27, 1, 14, 0,250, 0,224, 0,205, 0,184, 0,165, 0, + 145, 0,123, 0,106, 0, 86, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 17, 23, 6, 0, 23, 1, 1, 21,107,110,111,119,110, 52, 19,112, + 111,111,114, 18, 22, 6, 0, 23, 1, 1, 23, 97, 98,111,118,101, 24, 26,115, + 101,114,118,101, 15, 21, 6, 0, 19, 1, 1, 21,119, 97,114, 52, 19,112,111, + 111,114, 20, 20, 6, 0, 27, 1, 8, 25,110,111,116,104,105,110,103, 7,112, + 108, 97, 99,101,115, 18, 19, 6, 0, 23, 1, 1, 23, 98,101,103, 97,116, 90, + 27,116,114,117,116,104, 17, 18, 6, 0, 23, 1, 1, 21,100,119,101,108,116, + 21, 39,100,111,116,104, 19, 17, 6, 0, 27, 1, 1, 21,109,111,114,110,105, + 110,103, 52, 19,112,111,111,114, 17, 16, 6, 0, 21, 1, 1, 23,115,104,101, + 119, 90, 27,116,114,117,116,104, 24, 15, 6, 0, 27, 1, 1, 31,116,104,101, + 114,101,105,110, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 14, 6, 0, + 23, 1, 8, 25,115,109,111,116,101, 7,112,108, 97, 99,101,115, 11, 13, 6, + 0, 19, 1, 1, 0, 97,114,107, 72, 31, 15, 12, 6, 0, 21, 1, 8, 21,119, + 105,110,101, 58,119, 97,121,115, 19, 11, 6, 0, 21, 1, 1, 27,115,111,109, + 101, 98, 17,109,111,114,110,105,110,103, 19, 10, 6, 0, 27, 1, 1, 21, 98, + 101,116,119,101,101,110, 92, 18,115,111,109,101, 19, 9, 6, 0, 21, 1, 1, + 27,115, 97,118,101, 74, 36, 98,101,116,119,101,101,110, 21, 8, 6, 0, 25, + 1, 1, 27,116,104,111,117,103,104, 98, 17,109,111,114,110,105,110,103, 16, + 7, 6, 0, 21, 1, 1, 21,115,101,110,100, 49, 34,115,101,110,100, 18, 6, + 6, 0, 25, 1, 1, 21,119,105,115,100,111,109, 38, 36,115,101,110,100, 16, + 5, 6, 0, 23, 1, 9, 21, 97,110,103,101,114, 46,119, 97,121,115, 14, 4, + 6, 0, 19, 1, 1, 19, 99, 97,110, 19, 43,119, 97,114, 16, 3, 6, 0, 23, + 1, 1, 19,111,102,102,101,114, 48, 22,115,105,120, 16, 2, 6, 0, 23, 1, + 8, 21,119,111,114,107,115, 58,119, 97,121,115, 16, 1, 6, 0, 23, 1, 1, + 19, 0, 0, 0, 26, 45, 0, 0, 0, 25, 23, 13, 0, 0, 0, 7, 0, 48, 0, + 1,171, 1, 74, 1, 30, 0,126, 0,249, 0,212, 0, 48, 0, 81, 0, 0, 84, + 4, 7, 23, 17, 17, 1,129, 19,116, 97, 98,108,101,116, 52,116, 52, 5, 67, + 82, 69, 76, 7, 7, 23, 17, 17, 1,129, 3,116, 97, 98,108,101,116, 53,116, + 53, 8, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 53, 40, 97, + 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, + 89, 44, 32, 98, 32, 84, 69, 88, 84, 32, 85, 78, 73, 81, 85, 69, 44, 99, 44, + 100, 44,101, 41, 84, 4, 7, 23, 17, 17, 1,129, 19,116, 97, 98,108,101,116, + 52,116, 52, 5, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 52, + 40, 97, 32, 73, 78, 84, 32, 85, 78, 73, 81, 85, 69, 32, 78, 79, 84, 32, 78, + 85, 76, 76, 44, 32, 98, 32, 73, 78, 84, 32, 85, 78, 73, 81, 85, 69, 32, 78, + 79, 84, 32, 78, 85, 76, 76, 44, 99, 44,100, 44,101, 41, 35, 6, 6, 23, 55, + 17, 1, 0,105,110,100,101,120,115,113,108,105,116,101, 95, 97,117,116,111, + 105,110,100,101,120, 95,116, 52, 95, 50,116, 52, 7, 35, 5, 6, 23, 55, 17, + 1, 0,105,110,100,101,120,115,113,108,105,116,101, 95, 97,117,116,111,105, + 110,100,101,120, 95,116, 52, 95, 49,116, 52, 6, 42, 3, 6, 23, 17, 17, 1, + 65,116, 97, 98,108,101,116, 51,116, 51, 4, 67, 82, 69, 65, 84, 69, 32, 84, + 65, 66, 76, 69, 32,116, 51, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 95, + 2, 7, 23, 17, 17, 1,129, 41,116, 97, 98,108,101,116, 50,116, 50, 3, 67, + 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 50, 40, 97, 32, 73, 78, + 84, 44, 32, 98, 32, 73, 78, 84, 44, 32, 99, 32, 73, 78, 84, 44,100, 32, 73, + 78, 84, 44,101, 32, 73, 78, 84, 44, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, + 89, 40, 98, 44, 97, 41, 41, 87, 73, 84, 72, 79, 85, 84, 32, 82, 79, 87, 73, + 68, 83, 1, 7, 23, 17, 17, 1,129, 17,116, 97, 98,108,101,116, 49,116, 49, + 2, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 49, 40, 97, 32, + 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 89, + 44, 32, 98, 32, 73, 78, 84, 44, 32, 99, 32, 73, 78, 84, 44, 32,100, 32, 73, + 78, 84, 44, 32,101, 32, 73, 78, 84, 41, 2, 0, 0, 0, 1, 1,243, 0, 0, + 0, 0, 29, 1,243, 1,218, 1,209, 1,199, 1,187, 1,179, 1,169, 1,158, + 1,145, 1,136, 1,127, 1,117, 1,107, 1, 98, 1, 82, 1, 72, 1, 63, 1, + 51, 1, 42, 1, 30, 1, 20, 1, 12, 1, 3, 0,248, 0,239, 0,225, 0,216, + 0,207, 0,197, 0,188, 0,180, 0,170, 0,161, 0,152, 0,141, 0,129, 0, + 118, 0,106, 0, 97, 0, 0, 0, 0, 0, 0, 0, 8, 3, 21, 1,116,114,101, + 101, 49, 11, 3, 27, 1,116,104,121,115,101,108,102, 27, 10, 3, 25, 1,116, + 104,111,117,103,104, 8, 11, 3, 27, 1,116,104,101,114,101,105,110, 15, 10, + 3, 25, 1,116,101,109,112,108,101, 43, 8, 3, 21, 1,116,101,108,108, 25, + 8, 3, 21, 1,115,111,109,101, 11, 9, 3, 23, 1,115,109,111,116,101, 14, + 7, 3, 19, 1,115,105,120, 48, 8, 3, 21, 1,115,104,101,119, 16, 9, 3, + 23, 1,115,101,114,118,101, 37, 8, 3, 21, 1,115,101,110,100, 7, 8, 3, + 21, 1,115, 97,118,101, 9, 13, 3, 31, 1,115, 97, 99,114,105,102,105, 99, + 101, 24, 8, 3, 21, 1,112,111,111,114, 40, 10, 3, 25, 1,112,108, 97, 99, + 101,115, 28, 8, 3, 21, 1,112, 97,114,116, 30, 7, 3, 19, 1,111,105,108, + 46, 9, 3, 23, 1,111,102,102,101,114, 3, 11, 3, 27, 1,110,111,116,104, + 105,110,103, 20, 8, 3, 21, 1,110,101, 97,114, 36, 11, 3, 27, 1,109,111, + 114,110,105,110,103, 17, 8, 3, 21, 1,108,111,110,103, 35, 9, 3, 23, 1, + 107,110,111,119,110, 23, 15, 3, 35, 1,105,110,104, 97, 98,105,116, 97,110, + 116,115, 45, 8, 3, 21, 1,103,111,110,101, 32, 9, 3, 23, 1,102,114,117, + 105,116, 38, 9, 3, 23, 1,100,119,101,108,116, 18, 8, 3, 21, 1,100,111, + 116,104, 39, 8, 3, 21, 1,100,105,101,100, 47, 12, 3, 29, 1,100,101,112, + 97,114,116,101,100, 26, 10, 3, 25, 1, 99,117, 98,105,116,115, 33, 9, 3, + 23, 1, 99,104,105,108,100, 42, 7, 3, 19, 1, 99, 97,110, 4, 11, 3, 27, + 1, 98,101,116,119,101,101,110, 10, 9, 3, 23, 1, 98,101,103, 97,116, 19, + 8, 3, 21, 1, 98,101, 97,114, 29, 7, 3, 19, 1, 97,114,107, 13, 9, 3, + 23, 1, 97,110,103,101,114, 5, 9, 3, 23, 1, 97,110,103, 0, 0, 0, 28, + 8, 3, 21, 1,116,114,101,101, 49, 13, 1,104, 0, 7, 0, 24, 0, 1, 67, + 1, 13, 0,225, 0,177, 0,109, 1,171, 0, 24, 0, 0, 83, 14, 7, 21, 19, + 19, 8,129, 17,118,105,101,119,118, 50, 48,118, 50, 48, 67, 82, 69, 65, 84, + 69, 32, 86, 73, 69, 87, 32,118, 50, 48, 40, 97, 44, 98, 44, 99, 44,100, 44, + 101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44, + 100, 44,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 87, 72, 69, 82, 69, 32, 97, + 60, 62, 50, 53, 66, 12, 6, 21, 19, 19, 8,113,118,105,101,119,118, 48, 48, + 118, 48, 48, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 48, 48, 40, + 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, + 84, 32, 49, 44, 49, 44, 49, 44, 49, 44, 39,111,110,101, 39, 46, 11, 6, 23, + 21, 17, 1, 69,105,110,100,101,120,116, 50,101,100,116, 50, 14, 67, 82, 69, + 65, 84, 69, 32, 73, 78, 68, 69, 88, 32,116, 50,101,100, 32, 79, 78, 32,116, + 50, 40,101, 44,100, 41, 42, 10, 6, 23, 19, 17, 1, 63,105,110,100,101,120, + 116, 49,101,116, 49, 13, 67, 82, 69, 65, 84, 69, 32, 73, 78, 68, 69, 88, 32, + 116, 49,101, 32, 79, 78, 32,116, 49, 40,101, 41, 52, 9, 6, 23, 21, 17, 1, + 81,105,110,100,101,120,116, 51,120, 49,116, 51, 12, 67, 82, 69, 65, 84, 69, + 32, 73, 78, 68, 69, 88, 32,116, 51,120, 49, 32, 79, 78, 32,116, 51, 40, 97, + 44, 98, 44, 99, 44,100, 44,101, 41, 35, 8, 6, 23, 55, 17, 1, 0,105,110, + 100,101,120,115,113,108,105,116,101, 95, 97,117,116,111,105,110,100,101,120, + 95,116, 53, 95, 49,116, 53, 10, 0, 0, 0, 67, 17, 17, 1,129, 3,116, 97, + 98,108,101,116, 53,116, 53, 8, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, + 69, 32,116, 53, 40, 97, 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, + 65, 82, 89, 32, 75, 69, 89, 44, 32, 98, 32, 84, 69, 88, 84, 32, 85, 78, 83, + 13, 7, 21, 19, 19, 8,129, 17,118,105,101,119,118, 49, 48,118, 49, 48, 67, + 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 49, 48, 40, 97, 44, 98, 44, + 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, + 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 87, 72, 69, + 82, 69, 32, 97, 60, 62, 50, 53, 2, 0, 0, 0, 1, 1,240, 0, 0, 0, 0, + 24, 1,240, 1,220, 1,211, 1,199, 1,187, 1,176, 1,164, 1,148, 1,133, + 1,116, 1, 99, 1, 86, 1, 67, 1, 55, 1, 43, 1, 31, 1, 18, 1, 5, 0, + 249, 0,236, 0,224, 0,209, 0,191, 0,174, 0,157, 0,145, 0,132, 0,120, + 0,108, 0, 95, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 1, 0, + 1, 1, 0, 1, 49, 51, 38, 15, 12, 7, 1, 1, 1, 1, 0, 1, 48, 37, 93, + 7, 30, 11, 7, 1, 1, 1, 0, 0, 1, 47, 22, 16, 24, 11, 7, 1, 0, 1, + 1, 0, 1, 47, 16, 40, 12, 12, 7, 1, 1, 1, 1, 0, 1, 46, 28, 88, 22, + 2, 11, 7, 1, 1, 0, 1, 0, 1, 44, 48, 9, 19, 16, 7, 1, 1, 1, 0, + 23, 1, 42, 20, 18, 98,101,103, 97,116, 22, 16, 7, 1, 1, 0, 1, 23, 1, + 37, 17, 18,100,119,101,108,116, 16, 17, 7, 1, 1, 0, 1, 25, 1, 35, 38, + 22, 99,117, 98,105,116,115, 17, 14, 7, 1, 1, 1, 0, 19, 1, 34, 26, 15, + 97,114,107, 21, 11, 7, 1, 1, 1, 0, 0, 1, 32, 16, 7, 23, 12, 7, 1, + 1, 1, 1, 0, 1, 28, 17, 67, 31, 29, 11, 7, 1, 0, 1, 1, 0, 1, 25, + 7, 19, 11, 12, 7, 1, 1, 1, 1, 0, 1, 22, 45, 71, 28, 28, 12, 7, 1, + 1, 1, 1, 0, 1, 21, 22, 92, 18, 4, 11, 7, 1, 1, 0, 1, 0, 1, 21, + 22, 18, 18, 11, 7, 1, 1, 1, 1, 0, 9, 17, 29, 74, 36, 11, 7, 1, 1, + 1, 0, 0, 1, 17, 29, 74, 25, 18, 7, 1, 1, 1, 1, 25, 1, 15, 6, 3, + 11,116,101,109,112,108,101, 5, 12, 7, 1, 1, 1, 1, 0, 1, 12, 4, 38, + 36, 27, 16, 7, 1, 0, 1, 1, 23, 1, 10, 89, 14,115,101,114,118,101, 14, + 16, 7, 1, 1, 1, 1, 21, 1, 4, 41, 32, 35,110,101, 97,114, 3, 14, 7, + 9, 0, 1, 1, 21, 1, 68, 32,100,111,116,104, 13, 15, 7, 0, 1, 1, 1, + 21, 1, 21, 91, 38,110,101, 97,114, 6, 11, 7, 0, 1, 1, 1, 0, 1, 16, + 81, 25, 9, 10, 7, 0, 1, 1, 8, 0, 1, 16, 7, 10, 11, 7, 0, 1, 1, + 1, 0, 1, 7, 72, 31, 8, 11, 7, 0, 1, 1, 1, 0, 1, 6, 37, 31, 7, + 8, 7, 0, 0, 0, 0, 0, 1, 35, 8, 7, 0, 0, 0, 0, 0, 1, 34, 8, + 7, 0, 0, 0, 0, 0, 1, 33, 8, 7, 0, 0, 0, 23, 11, 7, 1, 0, 1, + 1, 0, 1, 49, 51, 38, 15, 2, 0, 0, 0, 1, 1,241, 0, 0, 0, 0, 18, + 1,241, 1,221, 1,211, 1,203, 1,193, 1,183, 1,173, 1,163, 1,151, 1, + 143, 1,133, 1,122, 1,109, 1,100, 1, 92, 1, 83, 1, 74, 1, 64, 1, 55, + 1, 46, 1, 34, 1, 22, 1, 13, 1, 4, 0,252, 0,241, 0,232, 0,218, 0, + 209, 0,200, 0,191, 0,182, 0,173, 0,163, 0,153, 0,144, 0,136, 0,127, + 0,116, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, + 25, 1,116,101,109,112,108,101, 48, 10, 3, 25, 1,116,101,109,112,108,101, + 15, 8, 3, 21, 1,115,111,109,101, 21, 7, 3, 19, 1,115,105,120, 11, 8, + 3, 21, 1,115,104,101,119, 38, 9, 3, 23, 1,115,101,114,118,101, 10, 9, + 3, 23, 1,115,101,114,118,101, 3, 8, 3, 21, 1,115,101,110,100, 40, 8, + 3, 21, 1,115,101,110,100, 29, 8, 3, 21, 1,115,101,110,100, 12, 8, 3, + 21, 1,115,101,110,100, 8, 8, 3, 21, 1,115, 97,118,101, 2, 13, 3, 31, + 1,115, 97, 99,114,105,102,105, 99,101, 23, 8, 3, 21, 1,112,111,111,114, + 16, 10, 3, 25, 1,112,108, 97, 99,101,115, 32, 7, 3, 19, 1,111,105,108, + 49, 8, 3, 21, 1,110,101, 97,114, 7, 8, 3, 21, 1,110,101, 97,114, 4, + 11, 3, 27, 1,109,111,114,110,105,110,103, 41, 11, 3, 27, 1,109,111,114, + 110,105,110,103, 26, 8, 3, 21, 1,103,111,110,101, 25, 8, 3, 21, 1,103, + 111,110,101, 5, 9, 3, 23, 1,100,119,101,108,116, 37, 8, 3, 21, 1,100, + 111,116,104, 44, 8, 3, 21, 1,100,111,116,104, 13, 7, 3, 21, 9,100,111, + 116,104, 8, 3, 21, 1,100,105,101,100, 14, 12, 3, 29, 1,100,101,112, 97, + 114,116,101,100, 46, 10, 3, 25, 1, 99,117, 98,105,116,115, 35, 9, 3, 23, + 1, 99,104,105,108,100, 36, 7, 3, 19, 1, 99, 97,110, 6, 11, 3, 27, 1, + 98,101,116,119,101,101,110, 17, 9, 3, 23, 1, 98,101,103, 97,116, 43, 9, + 3, 23, 1, 98,101,103, 97,116, 42, 9, 3, 23, 1, 98,101,103, 97,116, 39, + 9, 3, 23, 1, 98,101,103, 97,116, 9, 7, 3, 19, 1, 97,114,107, 34, 9, + 3, 23, 1, 97,110,103,101,114, 47, 9, 3, 23, 1, 97,110,103,101,108, 27, + 9, 3, 23, 1, 97, 98,111,118,101, 45, 0, 0, 0, 17, 10, 3, 25, 1,116, + 101,109,112,108,101, 48, 2, 0, 0, 0, 1, 1,239, 0, 0, 0, 0, 20, 1, + 239, 1,206, 1,192, 1,180, 1,166, 1,152, 1,138, 1,125, 1,109, 1, 97, + 1, 84, 1, 69, 1, 52, 1, 39, 1, 26, 1, 14, 1, 1, 0,243, 0,230, 0, + 217, 0,201, 0,185, 0,172, 0,159, 0,147, 0,133, 0,120, 0,102, 0, 89, + 0, 76, 0, 0, 0, 0, 12, 5, 21, 1, 1, 1,115,101,110,100, 26, 14, 40, + 12, 5, 21, 1, 1, 1,115, 97,118,101, 39, 45, 2, 17, 5, 31, 1, 1, 1, + 115, 97, 99,114,105,102,105, 99,101, 31, 6, 23, 12, 5, 21, 1, 1, 1,112, + 111,111,114, 19, 44, 16, 13, 5, 25, 8, 1, 1,112,108, 97, 99,101,115, 16, + 32, 11, 5, 19, 1, 1, 1,111,105,108, 38, 9, 49, 12, 5, 21, 1, 1, 1, + 110,101, 97,114, 38, 21, 7, 12, 5, 21, 1, 1, 1,110,101, 97,114, 35, 41, + 4, 15, 5, 27, 1, 1, 1,109,111,114,110,105,110,103, 17, 40, 26, 15, 5, + 27, 1, 1, 1,109,111,114,110,105,110,103, 13, 46, 41, 12, 5, 21, 1, 1, + 1,103,111,110,101, 28, 25, 5, 12, 5, 21, 1, 1, 1,103,111,110,101, 19, + 10, 25, 13, 5, 23, 1, 1, 1,100,119,101,108,116, 18, 17, 37, 12, 5, 21, + 1, 1, 1,100,111,116,104, 39, 4, 13, 11, 5, 21, 1, 1, 9,100,111,116, + 104, 32, 40, 12, 5, 21, 1, 1, 1,100,111,116,104, 9, 48, 44, 12, 5, 21, + 1, 1, 1,100,105,101,100, 27, 35, 14, 16, 5, 29, 1, 1, 1,100,101,112, + 97,114,116,101,100, 22, 28, 46, 14, 5, 25, 1, 1, 1, 99,117, 98,105,116, + 115, 22, 38, 35, 12, 5, 23, 1, 8, 1, 99,104,105,108,100, 17, 36, 11, 5, + 19, 1, 1, 1, 99, 97,110, 11, 2, 6, 15, 5, 27, 1, 1, 1, 98,101,116, + 119,101,101,110, 36, 29, 17, 12, 5, 23, 1, 8, 1, 98,101,103, 97,116, 50, + 9, 13, 5, 23, 1, 1, 1, 98,101,103, 97,116, 45, 3, 39, 13, 5, 23, 1, + 1, 1, 98,101,103, 97,116, 41, 5, 43, 13, 5, 23, 1, 1, 1, 98,101,103, + 97,116, 5, 20, 42, 11, 5, 19, 1, 1, 1, 97,114,107, 20, 26, 34, 13, 5, + 23, 1, 1, 1, 97,110,103,101,114, 40, 22, 47, 13, 5, 23, 1, 1, 1, 97, + 110,103,101,108, 3, 22, 27, 12, 5, 23, 1, 9, 1, 97, 98,111,118,101, 45, + 20, 13, 5, 23, 1, 1, 1, 0, 0, 0, 19, 12, 5, 21, 1, 1, 1,115,101, + 110,100, 26, 14, 40, 13, 0, 0, 0, 28, 0, 78, 0, 1,241, 1,226, 1,210, + 1,195, 1,180, 1,166, 1,151, 1,136, 1,121, 1,105, 1, 91, 1, 76, 1, + 61, 1, 46, 1, 29, 1, 14, 0,252, 0,238, 0,224, 0,209, 0,194, 0,177, + 0,157, 0,143, 0,128, 0,110, 0, 94, 0, 78, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 28, 6, 0, 1, 1, 1, 23, 17, 67, 31,119, + 111,114,107,115, 14, 27, 6, 0, 1, 1, 1, 23, 22, 71, 3, 97,110,103,101, + 108, 16, 26, 6, 0, 1, 1, 1, 27, 40, 98, 17,109,111,114,110,105,110,103, + 13, 25, 6, 0, 1, 1, 1, 21, 10, 7, 19,103,111,110,101, 12, 24, 6, 0, + 1, 1, 9, 21, 43, 46,119, 97,121,115, 18, 23, 6, 0, 1, 1, 1, 31, 6, + 37, 31,115, 97, 99,114,105,102,105, 99,101, 15, 22, 6, 0, 1, 1, 1, 25, + 45, 71, 28,116,104,111,117,103,104, 13, 21, 6, 0, 1, 1, 1, 21, 22, 92, + 18,115,111,109,101, 13, 20, 6, 0, 9, 1, 1, 23, 2, 45, 97, 98,111,118, + 101, 12, 19, 6, 0, 1, 1, 8, 21, 4, 58,119, 97,121,115, 12, 18, 6, 0, + 1, 1, 1, 19, 44, 19, 43,119, 97,114, 16, 17, 6, 0, 1, 1, 1, 27, 29, + 74, 36, 98,101,116,119,101,101,110, 13, 16, 6, 0, 1, 1, 1, 21, 44, 52, + 19,112,111,111,114, 15, 15, 6, 0, 1, 1, 1, 25, 6, 3, 11,116,101,109, + 112,108,101, 13, 14, 6, 0, 1, 1, 1, 21, 35, 48, 27,100,105,101,100, 13, + 13, 6, 0, 1, 1, 1, 21, 4, 21, 39,100,111,116,104, 13, 12, 6, 0, 1, + 1, 1, 21, 4, 38, 36,115,101,110,100, 12, 11, 6, 0, 1, 1, 1, 19, 13, + 48, 22,115,105,120, 14, 10, 6, 0, 1, 1, 1, 23, 41, 89, 14,115,101,114, + 118,101, 13, 9, 6, 0, 8, 1, 1, 23, 16, 50, 98,101,103, 97,116, 13, 8, + 6, 0, 1, 1, 1, 21, 42, 49, 34,115,101,110,100, 13, 7, 6, 0, 1, 1, + 1, 21, 21, 91, 38,110,101, 97,114, 12, 6, 6, 0, 1, 1, 1, 19, 2, 37, + 11, 99, 97,110, 13, 5, 6, 0, 1, 1, 1, 21, 25, 27, 28,103,111,110,101, + 13, 4, 6, 0, 1, 1, 1, 21, 41, 32, 35,110,101, 97,114, 14, 3, 6, 0, + 1, 1, 1, 23, 32, 24, 26,115,101,114,118,101, 13, 2, 6, 0, 1, 1, 1, + 21, 45, 14, 39,115, 97,118,101, 13, 1, 6, 0, 1, 1, 1, 21, 40, 68, 32, + 100,111,116,104, 13, 0, 0, 0, 22, 0,166, 0, 1,241, 1,226, 1,210, 1, + 194, 1,183, 1,169, 1,152, 1,137, 1,121, 1,106, 1, 90, 1, 75, 1, 57, + 1, 41, 1, 25, 1, 10, 0,250, 0,231, 0,215, 0,198, 0,184, 0,166, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 50, 6, 0, 1, 1, 1, 27, 9, 92, 29,116,104,101,114,101,105,110, 12, 49, + 6, 0, 1, 1, 1, 19, 9, 51, 38,111,105,108, 15, 48, 6, 0, 1, 1, 1, + 25, 37, 93, 7,116,101,109,112,108,101, 14, 47, 6, 0, 1, 1, 1, 23, 22, + 16, 40, 97,110,103,101,114, 17, 46, 6, 0, 1, 1, 1, 29, 28, 88, 22,100, + 101,112, 97,114,116,101,100, 14, 45, 6, 0, 1, 1, 1, 23, 47, 54, 12, 97, + 98,111,118,101, 13, 44, 6, 0, 1, 1, 1, 21, 48, 15, 9,100,111,116,104, + 14, 43, 6, 0, 1, 1, 1, 23, 5, 23, 41, 98,101,103, 97,116, 14, 42, 6, + 0, 1, 1, 1, 23, 20, 18, 5, 98,101,103, 97,116, 16, 41, 6, 0, 1, 1, + 1, 27, 46, 92, 13,109,111,114,110,105,110,103, 13, 40, 6, 0, 1, 1, 1, + 21, 14, 30, 26,115,101,110,100, 14, 39, 6, 0, 1, 1, 1, 23, 3, 21, 45, + 98,101,103, 97,116, 13, 38, 6, 0, 1, 1, 1, 21, 10, 97, 34,115,104,101, + 119, 14, 37, 6, 0, 1, 1, 1, 23, 17, 66, 18,100,119,101,108,116, 13, 36, + 6, 0, 8, 1, 1, 23, 52, 17, 99,104,105,108,100, 15, 35, 6, 0, 1, 1, + 1, 25, 38, 34, 22, 99,117, 98,105,116,115, 12, 34, 6, 0, 1, 1, 1, 19, + 26, 15, 20, 97,114,107, 9, 33, 6, 0, 1, 1, 1, 0, 7, 72, 31, 14, 32, + 6, 0, 1, 1, 8, 25, 16, 7,112,108, 97, 99,101,115, 14, 31, 6, 0, 1, + 1, 1, 23, 39, 90, 27,116,114,117,116,104, 13, 30, 6, 0, 1, 1, 1, 21, + 16, 81, 25,119, 97,108,107, 13, 29, 6, 0, 1, 1, 1, 21, 34, 62, 27,115, + 101,110,100, 10, 0, 0, 0, 41, 0,116, 0, 1,251, 1,241, 1,231, 1,221, + 1,211, 1,203, 1,193, 1,183, 1,173, 1,163, 1,151, 1,143, 1,133, 1, + 122, 1,109, 1,100, 1, 92, 1, 83, 1, 74, 1, 64, 1, 55, 1, 46, 1, 34, + 1, 22, 1, 13, 1, 4, 0,252, 0,241, 0,232, 0,218, 0,209, 0,200, 0, + 191, 0,182, 0,173, 0,163, 0,153, 0,144, 0,136, 0,127, 0,116, 0,105, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,116,101, + 109,112,108,101, 48, 10, 3, 25, 1,116,101,109,112,108,101, 15, 8, 3, 21, + 1,115,111,109,101, 21, 7, 3, 19, 1,115,105,120, 11, 8, 3, 21, 1,115, + 104,101,119, 38, 9, 3, 23, 1,115,101,114,118,101, 10, 9, 3, 23, 1,115, + 101,114,118,101, 3, 8, 3, 21, 1,115,101,110,100, 40, 8, 3, 21, 1,115, + 101,110,100, 29, 8, 3, 21, 1,115,101,110,100, 12, 8, 3, 21, 1,115,101, + 110,100, 8, 8, 3, 21, 1,115, 97,118,101, 2, 13, 3, 31, 1,115, 97, 99, + 114,105,102,105, 99,101, 23, 8, 3, 21, 1,112,111,111,114, 16, 10, 3, 25, + 1,112,108, 97, 99,101,115, 32, 7, 3, 19, 1,111,105,108, 49, 8, 3, 21, + 1,110,101, 97,114, 7, 8, 3, 21, 1,110,101, 97,114, 4, 11, 3, 27, 1, + 109,111,114,110,105,110,103, 41, 11, 3, 27, 1,109,111,114,110,105,110,103, + 26, 8, 3, 21, 1,103,111,110,101, 25, 8, 3, 21, 1,103,111,110,101, 5, + 9, 3, 23, 1,100,119,101,108,116, 37, 8, 3, 21, 1,100,111,116,104, 44, + 8, 3, 21, 1,100,111,116,104, 13, 7, 3, 21, 9,100,111,116,104, 8, 3, + 21, 1,100,105,101,100, 14, 12, 3, 29, 1,100,101,112, 97,114,116,101,100, + 46, 10, 3, 25, 1, 99,117, 98,105,116,115, 35, 9, 3, 23, 1, 99,104,105, + 108,100, 36, 7, 3, 19, 1, 99, 97,110, 6, 11, 3, 27, 1, 98,101,116,119, + 101,101,110, 17, 9, 3, 23, 1, 98,101,103, 97,116, 43, 9, 3, 23, 1, 98, + 101,103, 97,116, 42, 9, 3, 23, 1, 98,101,103, 97,116, 39, 9, 3, 23, 1, + 98,101,103, 97,116, 9, 7, 3, 19, 1, 97,114,107, 34, 9, 3, 23, 1, 97, + 110,103,101,114, 47, 9, 3, 23, 1, 97,110,103,101,108, 27, 9, 3, 23, 1, + 97, 98,111,118,101, 45, 9, 3, 23, 1, 97, 98,111,118,101, 20, 4, 3, 0, + 1, 33, 10, 0, 0, 0, 8, 1,178, 0, 1,244, 1,233, 1,223, 1,214, 1, + 206, 1,197, 1,188, 1,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 3, 23, 1,119,111,114,107,115, 28, 8, 3, 21, 1,119, 97,121,115, 24, 8, + 3, 21, 1,119, 97,121,115, 19, 7, 3, 19, 1,119, 97,114, 18, 8, 3, 21, + 1,119, 97,108,107, 30, 9, 3, 23, 1,116,114,117,116,104, 31, 10, 3, 25, + 1,116,104,111,117,103,104, 22, 11, 3, 27, 1,116,104,101,114,101,105,110, + 50, 10, 0, 0, 0, 31, 0, 89, 0, 1,247, 1,233, 1,220, 1,206, 1,192, + 1,180, 1,166, 1,152, 1,138, 1,125, 1,109, 1, 97, 1, 84, 1, 69, 1, + 52, 1, 39, 1, 26, 1, 14, 1, 1, 0,243, 0,230, 0,217, 0,201, 0,185, + 0,172, 0,159, 0,147, 0,133, 0,120, 0,102, 0, 89, 0, 76, 0, 0, 0, + 0, 0, 0, 0, 13, 1, 1,115,101,110,100, 26, 14, 40, 12, 5, 21, 1, 1, + 1,115, 97,118,101, 39, 45, 2, 17, 5, 31, 1, 1, 1,115, 97, 99,114,105, + 102,105, 99,101, 31, 6, 23, 12, 5, 21, 1, 1, 1,112,111,111,114, 19, 44, + 16, 13, 5, 25, 8, 1, 1,112,108, 97, 99,101,115, 16, 32, 11, 5, 19, 1, + 1, 1,111,105,108, 38, 9, 49, 12, 5, 21, 1, 1, 1,110,101, 97,114, 38, + 21, 7, 12, 5, 21, 1, 1, 1,110,101, 97,114, 35, 41, 4, 15, 5, 27, 1, + 1, 1,109,111,114,110,105,110,103, 17, 40, 26, 15, 5, 27, 1, 1, 1,109, + 111,114,110,105,110,103, 13, 46, 41, 12, 5, 21, 1, 1, 1,103,111,110,101, + 28, 25, 5, 12, 5, 21, 1, 1, 1,103,111,110,101, 19, 10, 25, 13, 5, 23, + 1, 1, 1,100,119,101,108,116, 18, 17, 37, 12, 5, 21, 1, 1, 1,100,111, + 116,104, 39, 4, 13, 11, 5, 21, 1, 1, 9,100,111,116,104, 32, 40, 12, 5, + 21, 1, 1, 1,100,111,116,104, 9, 48, 44, 12, 5, 21, 1, 1, 1,100,105, + 101,100, 27, 35, 14, 16, 5, 29, 1, 1, 1,100,101,112, 97,114,116,101,100, + 22, 28, 46, 14, 5, 25, 1, 1, 1, 99,117, 98,105,116,115, 22, 38, 35, 12, + 5, 23, 1, 8, 1, 99,104,105,108,100, 17, 36, 11, 5, 19, 1, 1, 1, 99, + 97,110, 11, 2, 6, 15, 5, 27, 1, 1, 1, 98,101,116,119,101,101,110, 36, + 29, 17, 12, 5, 23, 1, 8, 1, 98,101,103, 97,116, 50, 9, 13, 5, 23, 1, + 1, 1, 98,101,103, 97,116, 45, 3, 39, 13, 5, 23, 1, 1, 1, 98,101,103, + 97,116, 41, 5, 43, 13, 5, 23, 1, 1, 1, 98,101,103, 97,116, 5, 20, 42, + 11, 5, 19, 1, 1, 1, 97,114,107, 20, 26, 34, 13, 5, 23, 1, 1, 1, 97, + 110,103,101,114, 40, 22, 47, 13, 5, 23, 1, 1, 1, 97,110,103,101,108, 3, + 22, 27, 12, 5, 23, 1, 9, 1, 97, 98,111,118,101, 45, 20, 13, 5, 23, 1, + 1, 1, 97, 98,111,118,101, 12, 47, 45, 8, 5, 0, 1, 1, 1, 31, 7, 33, + 10, 0, 0, 0, 18, 1, 13, 0, 1,243, 1,230, 1,217, 1,203, 1,189, 1, + 176, 1,164, 1,151, 1,136, 1,121, 1,105, 1, 90, 1, 76, 1, 63, 1, 51, + 1, 39, 1, 27, 1, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 13, 5, 23, 1, 1, 1,119,111,114,107,115, 31, 17, 28, 11, 5, + 21, 9, 1, 1,119, 97,121,115, 43, 24, 11, 5, 21, 8, 1, 1,119, 97,121, + 115, 4, 19, 11, 5, 19, 1, 1, 1,119, 97,114, 43, 44, 18, 12, 5, 21, 1, + 1, 1,119, 97,108,107, 25, 16, 30, 13, 5, 23, 1, 1, 1,116,114,117,116, + 104, 27, 39, 31, 14, 5, 25, 1, 1, 1,116,104,111,117,103,104, 28, 45, 22, + 15, 5, 27, 1, 1, 1,116,104,101,114,101,105,110, 29, 9, 50, 14, 5, 25, + 1, 1, 1,116,101,109,112,108,101, 11, 6, 15, 14, 5, 25, 1, 1, 1,116, + 101,109,112,108,101, 7, 37, 48, 12, 5, 21, 1, 1, 1,115,111,109,101, 18, + 22, 21, 11, 5, 19, 1, 1, 1,115,105,120, 22, 13, 11, 12, 5, 21, 1, 1, + 1,115,104,101,119, 34, 10, 38, 13, 5, 23, 1, 1, 1,115,101,114,118,101, + 26, 32, 3, 13, 5, 23, 1, 1, 1,115,101,114,118,101, 14, 41, 10, 12, 5, + 21, 1, 1, 1,115,101,110,100, 36, 4, 12, 12, 5, 21, 1, 1, 1,115,101, + 110,100, 34, 42, 8, 12, 5, 21, 1, 1, 1,115,101,110,100, 27, 34, 29, 10, + 0, 0, 0, 28, 0, 82, 0, 1,241, 1,226, 1,211, 1,197, 1,181, 1,166, + 1,151, 1,137, 1,121, 1,104, 1, 84, 1, 73, 1, 59, 1, 41, 1, 26, 1, + 11, 0,253, 0,238, 0,223, 0,207, 0,191, 0,175, 0,159, 0,144, 0,129, + 0,113, 0, 97, 0, 82, 0, 68, 0, 0, 0, 0, 0, 14, 1, 1, 19, 26, 34, + 15, 20, 97,114,107, 14, 6, 1, 1, 1, 1, 21, 25, 5, 27, 28,103,111,110, + 101, 15, 6, 1, 1, 1, 1, 23, 22, 47, 16, 40, 97,110,103,101,114, 15, 6, + 1, 1, 1, 1, 23, 22, 27, 71, 3, 97,110,103,101,108, 14, 6, 1, 1, 1, + 1, 21, 22, 21, 92, 18,115,111,109,101, 14, 6, 1, 1, 1, 1, 21, 21, 7, + 91, 38,110,101, 97,114, 15, 6, 1, 1, 1, 1, 23, 20, 42, 18, 5, 98,101, + 103, 97,116, 15, 6, 1, 1, 1, 1, 23, 17, 37, 66, 18,100,119,101,108,116, + 15, 6, 1, 1, 1, 1, 23, 17, 28, 67, 31,119,111,114,107,115, 15, 6, 1, + 1, 1, 8, 25, 16, 32, 7,112,108, 97, 99,101,115, 14, 6, 1, 1, 1, 1, + 21, 16, 30, 81, 25,119, 97,108,107, 14, 6, 1, 1, 1, 1, 21, 14, 40, 30, + 26,115,101,110,100, 13, 6, 1, 1, 1, 1, 19, 13, 11, 48, 22,115,105,120, + 14, 6, 1, 1, 1, 1, 21, 10, 38, 97, 34,115,104,101,119, 14, 6, 1, 1, + 1, 1, 21, 10, 25, 7, 19,103,111,110,101, 17, 6, 1, 1, 1, 1, 27, 9, + 50, 92, 29,116,104,101,114,101,105,110, 13, 6, 1, 1, 1, 1, 19, 9, 49, + 51, 38,111,105,108, 10, 6, 1, 1, 1, 1, 0, 7, 33, 72, 31, 19, 6, 1, + 1, 1, 1, 31, 6, 23, 37, 31,115, 97, 99,114,105,102,105, 99,101, 16, 6, + 1, 1, 1, 1, 25, 6, 15, 3, 11,116,101,109,112,108,101, 15, 6, 1, 1, + 1, 1, 23, 5, 43, 23, 41, 98,101,103, 97,116, 13, 6, 1, 1, 1, 8, 21, + 4, 19, 58,119, 97,121,115, 14, 6, 1, 1, 1, 1, 21, 4, 13, 21, 39,100, + 111,116,104, 14, 6, 1, 1, 1, 1, 21, 4, 12, 38, 36,115,101,110,100, 15, + 6, 1, 1, 1, 1, 23, 3, 39, 21, 45, 98,101,103, 97,116, 13, 6, 1, 1, + 1, 1, 19, 2, 6, 37, 11, 99, 97,110, 14, 6, 9, 1, 1, 1, 23, 20, 2, + 45, 97, 98,111,118,101, 14, 6, 8, 1, 1, 1, 23, 36, 52, 17, 99,104,105, + 108,100, 14, 6, 8, 1, 1, 1, 23, 9, 16, 50, 98,101,103, 97,116, 10, 0, + 0, 0, 21, 0,177, 0, 1,237, 1,219, 1,203, 1,188, 1,173, 1,156, 1, + 139, 1,123, 1,109, 1, 91, 1, 76, 1, 60, 1, 45, 1, 31, 1, 16, 1, 2, + 0,243, 0,226, 0,208, 0,192, 0,177, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 14, 6, 1, 1, 1, 1, 21, 48, 44, 15, 9,100,111,116,104, + 15, 6, 1, 1, 1, 1, 23, 47, 45, 54, 12, 97, 98,111,118,101, 17, 6, 1, + 1, 1, 1, 27, 46, 41, 92, 13,109,111,114,110,105,110,103, 16, 6, 1, 1, + 1, 1, 25, 45, 22, 71, 28,116,104,111,117,103,104, 14, 6, 1, 1, 1, 1, + 21, 45, 2, 14, 39,115, 97,118,101, 13, 6, 1, 1, 1, 1, 19, 44, 18, 19, + 43,119, 97,114, 14, 6, 1, 1, 1, 1, 21, 44, 16, 52, 19,112,111,111,114, + 13, 6, 1, 1, 1, 9, 21, 43, 24, 46,119, 97,121,115, 14, 6, 1, 1, 1, + 1, 21, 42, 8, 49, 34,115,101,110,100, 15, 6, 1, 1, 1, 1, 23, 41, 10, + 89, 14,115,101,114,118,101, 14, 6, 1, 1, 1, 1, 21, 41, 4, 32, 35,110, + 101, 97,114, 17, 6, 1, 1, 1, 1, 27, 40, 26, 98, 17,109,111,114,110,105, + 110,103, 13, 6, 1, 9, 1, 1, 21, 40, 68, 32,100,111,116,104, 15, 6, 1, + 1, 1, 1, 23, 39, 31, 90, 27,116,114,117,116,104, 16, 6, 1, 1, 1, 1, + 25, 38, 35, 34, 22, 99,117, 98,105,116,115, 16, 6, 1, 1, 1, 1, 25, 37, + 48, 93, 7,116,101,109,112,108,101, 14, 6, 1, 1, 1, 1, 21, 35, 14, 48, + 27,100,105,101,100, 14, 6, 1, 1, 1, 1, 21, 34, 29, 62, 27,115,101,110, + 100, 15, 6, 1, 1, 1, 1, 23, 32, 3, 24, 26,115,101,114,118,101, 17, 6, + 1, 1, 1, 1, 27, 29, 17, 74, 36, 98,101,116,119,101,101,110, 18, 6, 1, + 1, 1, 1, 29, 28, 46, 88, 22,100,101,112, 97,114,116,101,100, 10, 0, 0, + 0, 32, 0, 95, 0, 1,247, 1,238, 1,229, 1,220, 1,211, 1,199, 1,187, + 1,176, 1,164, 1,148, 1,133, 1,116, 1, 99, 1, 86, 1, 67, 1, 55, 1, + 43, 1, 31, 1, 18, 1, 5, 0,249, 0,236, 0,224, 0,209, 0,191, 0,174, + 0,157, 0,145, 0,132, 0,120, 0,108, 0, 95, 0, 83, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 1, 1, 0, 1, 49, 51, 38, 15, 12, 7, 1, + 1, 1, 1, 0, 1, 48, 37, 93, 7, 30, 11, 7, 1, 1, 1, 0, 0, 1, 47, + 22, 16, 24, 11, 7, 1, 0, 1, 1, 0, 1, 47, 16, 40, 12, 12, 7, 1, 1, + 1, 1, 0, 1, 46, 28, 88, 22, 2, 11, 7, 1, 1, 0, 1, 0, 1, 44, 48, + 9, 19, 16, 7, 1, 1, 1, 0, 23, 1, 42, 20, 18, 98,101,103, 97,116, 22, + 16, 7, 1, 1, 0, 1, 23, 1, 37, 17, 18,100,119,101,108,116, 16, 17, 7, + 1, 1, 0, 1, 25, 1, 35, 38, 22, 99,117, 98,105,116,115, 17, 14, 7, 1, + 1, 1, 0, 19, 1, 34, 26, 15, 97,114,107, 21, 11, 7, 1, 1, 1, 0, 0, + 1, 32, 16, 7, 23, 12, 7, 1, 1, 1, 1, 0, 1, 28, 17, 67, 31, 29, 11, + 7, 1, 0, 1, 1, 0, 1, 25, 7, 19, 11, 12, 7, 1, 1, 1, 1, 0, 1, + 22, 45, 71, 28, 28, 12, 7, 1, 1, 1, 1, 0, 1, 21, 22, 92, 18, 4, 11, + 7, 1, 1, 0, 1, 0, 1, 21, 22, 18, 18, 11, 7, 1, 1, 1, 1, 0, 9, + 17, 29, 74, 36, 11, 7, 1, 1, 1, 0, 0, 1, 17, 29, 74, 25, 18, 7, 1, + 1, 1, 1, 25, 1, 15, 6, 3, 11,116,101,109,112,108,101, 5, 12, 7, 1, + 1, 1, 1, 0, 1, 12, 4, 38, 36, 27, 16, 7, 1, 0, 1, 1, 23, 1, 10, + 89, 14,115,101,114,118,101, 14, 16, 7, 1, 1, 1, 1, 21, 1, 4, 41, 32, + 35,110,101, 97,114, 3, 14, 7, 9, 0, 1, 1, 21, 1, 68, 32,100,111,116, + 104, 13, 15, 7, 0, 1, 1, 1, 21, 1, 21, 91, 38,110,101, 97,114, 6, 11, + 7, 0, 1, 1, 1, 0, 1, 16, 81, 25, 9, 10, 7, 0, 1, 1, 8, 0, 1, + 16, 7, 10, 11, 7, 0, 1, 1, 1, 0, 1, 7, 72, 31, 8, 11, 7, 0, 1, + 1, 1, 0, 1, 6, 37, 31, 7, 8, 7, 0, 0, 0, 0, 0, 1, 35, 8, 7, + 0, 0, 0, 0, 0, 1, 34, 8, 7, 0, 0, 0, 0, 0, 1, 33, 8, 7, 0, + 0, 0, 0, 0, 1, 32, 8, 7, 0, 0, 0, 0, 0, 1, 31, 10, 0, 0, 0, + 2, 1,231, 0, 1,244, 1,231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 1, 1, 1, 1, 0, 1, 49, 9, 51, + 38, 26, 11, 7, 1, 1, 0, 1, 0, 1, 49, 9, 38, 20, 13, 0, 0, 0, 23, + 0, 67, 0, 1,238, 1,220, 1,202, 1,186, 1,168, 1,148, 1,130, 1,107, + 1, 86, 1, 65, 1, 44, 1, 27, 1, 14, 0,250, 0,224, 0,205, 0,184, 0, + 165, 0,145, 0,123, 0,106, 0, 86, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 23, 6, 0, 23, 1, 1, 21,107,110,111,119,110, 52, + 19,112,111,111,114, 18, 22, 6, 0, 23, 1, 1, 23, 97, 98,111,118,101, 24, + 26,115,101,114,118,101, 15, 21, 6, 0, 19, 1, 1, 21,119, 97,114, 52, 19, + 112,111,111,114, 20, 20, 6, 0, 27, 1, 8, 25,110,111,116,104,105,110,103, + 7,112,108, 97, 99,101,115, 18, 19, 6, 0, 23, 1, 1, 23, 98,101,103, 97, + 116, 90, 27,116,114,117,116,104, 17, 18, 6, 0, 23, 1, 1, 21,100,119,101, + 108,116, 21, 39,100,111,116,104, 19, 17, 6, 0, 27, 1, 1, 21,109,111,114, + 110,105,110,103, 52, 19,112,111,111,114, 17, 16, 6, 0, 21, 1, 1, 23,115, + 104,101,119, 90, 27,116,114,117,116,104, 24, 15, 6, 0, 27, 1, 1, 31,116, + 104,101,114,101,105,110, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 14, + 6, 0, 23, 1, 8, 25,115,109,111,116,101, 7,112,108, 97, 99,101,115, 11, + 13, 6, 0, 19, 1, 1, 0, 97,114,107, 72, 31, 15, 12, 6, 0, 21, 1, 8, + 21,119,105,110,101, 58,119, 97,121,115, 19, 11, 6, 0, 21, 1, 1, 27,115, + 111,109,101, 98, 17,109,111,114,110,105,110,103, 19, 10, 6, 0, 27, 1, 1, + 21, 98,101,116,119,101,101,110, 92, 18,115,111,109,101, 19, 9, 6, 0, 21, + 1, 1, 27,115, 97,118,101, 74, 36, 98,101,116,119,101,101,110, 21, 8, 6, + 0, 25, 1, 1, 27,116,104,111,117,103,104, 98, 17,109,111,114,110,105,110, + 103, 16, 7, 6, 0, 21, 1, 1, 21,115,101,110,100, 49, 34,115,101,110,100, + 18, 6, 6, 0, 25, 1, 1, 21,119,105,115,100,111,109, 38, 36,115,101,110, + 100, 16, 5, 6, 0, 23, 1, 9, 21, 97,110,103,101,114, 46,119, 97,121,115, + 14, 4, 6, 0, 19, 1, 1, 19, 99, 97,110, 19, 43,119, 97,114, 16, 3, 6, + 0, 23, 1, 1, 19,111,102,102,101,114, 48, 22,115,105,120, 16, 2, 6, 0, + 23, 1, 8, 21,119,111,114,107,115, 58,119, 97,121,115, 16, 1, 6, 0, 23, + 1, 1, 19,116,114,117,116,104, 37, 11, 99, 97,110, 13, 0, 0, 0, 22, 0, + 64, 0, 1,230, 1,213, 1,191, 1,169, 1,148, 1,130, 1,108, 1, 89, 1, + 70, 1, 51, 1, 34, 1, 16, 0,253, 0,233, 0,214, 0,194, 0,174, 0,151, + 0,132, 0,109, 0, 90, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 45, 6, 0, 35, 1, 1, 23,105,110,104, 97, 98,105,116, 97,110,116, + 115, 23, 41, 98,101,103, 97,116, 17, 44, 6, 0, 23, 1, 1, 21, 97,110,103, + 101,108, 48, 27,100,105,101,100, 21, 43, 6, 0, 25, 1, 1, 27,116,101,109, + 112,108,101, 74, 36, 98,101,116,119,101,101,110, 17, 42, 6, 0, 23, 1, 1, + 21, 99,104,105,108,100, 81, 25,119, 97,108,107, 21, 41, 6, 0, 21, 1, 1, + 31,119, 97,121,115, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 40, 6, + 0, 21, 1, 1, 25,112,111,111,114, 93, 7,116,101,109,112,108,101, 18, 39, + 6, 0, 21, 1, 1, 25,100,111,116,104, 3, 11,116,101,109,112,108,101, 17, + 38, 6, 0, 23, 1, 1, 21,102,114,117,105,116, 62, 27,115,101,110,100, 18, + 37, 6, 0, 23, 1, 1, 23,115,101,114,118,101, 90, 27,116,114,117,116,104, + 17, 36, 6, 0, 21, 1, 1, 23,110,101, 97,114, 90, 27,116,114,117,116,104, + 16, 35, 6, 0, 21, 1, 1, 21,108,111,110,103, 14, 39,115, 97,118,101, 15, + 34, 6, 0, 21, 1, 1, 19,119, 97,108,107, 15, 20, 97,114,107, 17, 33, 6, + 0, 25, 1, 9, 21, 99,117, 98,105,116,115, 46,119, 97,121,115, 17, 32, 6, + 0, 21, 1, 1, 23,103,111,110,101, 23, 41, 98,101,103, 97,116, 17, 31, 6, + 0, 23, 1, 1, 21,119,104,105,108,101, 49, 34,115,101,110,100, 20, 30, 6, + 0, 21, 1, 1, 29,112, 97,114,116, 88, 22,100,101,112, 97,114,116,101,100, + 16, 29, 6, 0, 21, 1, 1, 21, 98,101, 97,114, 92, 18,115,111,109,101, 19, + 28, 6, 0, 25, 1, 1, 23,112,108, 97, 99,101,115, 23, 41, 98,101,103, 97, + 116, 20, 27, 6, 0, 27, 1, 1, 23,116,104,121,115,101,108,102, 54, 12, 97, + 98,111,118,101, 20, 26, 6, 0, 29, 1, 1, 21,100,101,112, 97,114,116,101, + 100, 92, 18,115,111,109,101, 15, 25, 6, 0, 21, 1, 1, 19,116,101,108,108, + 19, 43,119, 97,114, 24, 24, 6, 0, 31, 1, 1, 27,115, 97, 99,114,105,102, + 105, 99,101, 92, 13,109,111,114,110,105,110,103, 13, 0, 0, 0, 5, 1,162, + 0, 1,239, 1,221, 1,203, 1,182, 1,162, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 50, 6, 0, 23, 1, 1, + 23,119,114, 97,116,104, 21, 45, 98,101,103, 97,116, 19, 49, 6, 0, 21, 1, + 1, 27,116,114,101,101, 98, 17,109,111,114,110,105,110,103, 16, 48, 6, 0, + 19, 1, 1, 23,115,105,120, 71, 3, 97,110,103,101,108, 16, 47, 6, 0, 21, + 1, 1, 21,100,105,101,100, 7, 19,103,111,110,101, 15, 46, 6, 0, 19, 1, + 1, 21,111,105,108, 81, 25,119, 97,108,107, 10, 0, 0, 0, 40, 0,106, 0, + 1,246, 1,236, 1,226, 1,218, 1,209, 1,199, 1,187, 1,179, 1,169, 1, + 158, 1,145, 1,136, 1,127, 1,117, 1,107, 1, 98, 1, 82, 1, 72, 1, 63, + 1, 51, 1, 42, 1, 30, 1, 20, 1, 12, 1, 3, 0,248, 0,239, 0,225, 0, + 216, 0,207, 0,197, 0,188, 0,180, 0,170, 0,161, 0,152, 0,141, 0,129, + 0,118, 0,106, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,116,114, + 101,101, 49, 11, 3, 27, 1,116,104,121,115,101,108,102, 27, 10, 3, 25, 1, + 116,104,111,117,103,104, 8, 11, 3, 27, 1,116,104,101,114,101,105,110, 15, + 10, 3, 25, 1,116,101,109,112,108,101, 43, 8, 3, 21, 1,116,101,108,108, + 25, 8, 3, 21, 1,115,111,109,101, 11, 9, 3, 23, 1,115,109,111,116,101, + 14, 7, 3, 19, 1,115,105,120, 48, 8, 3, 21, 1,115,104,101,119, 16, 9, + 3, 23, 1,115,101,114,118,101, 37, 8, 3, 21, 1,115,101,110,100, 7, 8, + 3, 21, 1,115, 97,118,101, 9, 13, 3, 31, 1,115, 97, 99,114,105,102,105, + 99,101, 24, 8, 3, 21, 1,112,111,111,114, 40, 10, 3, 25, 1,112,108, 97, + 99,101,115, 28, 8, 3, 21, 1,112, 97,114,116, 30, 7, 3, 19, 1,111,105, + 108, 46, 9, 3, 23, 1,111,102,102,101,114, 3, 11, 3, 27, 1,110,111,116, + 104,105,110,103, 20, 8, 3, 21, 1,110,101, 97,114, 36, 11, 3, 27, 1,109, + 111,114,110,105,110,103, 17, 8, 3, 21, 1,108,111,110,103, 35, 9, 3, 23, + 1,107,110,111,119,110, 23, 15, 3, 35, 1,105,110,104, 97, 98,105,116, 97, + 110,116,115, 45, 8, 3, 21, 1,103,111,110,101, 32, 9, 3, 23, 1,102,114, + 117,105,116, 38, 9, 3, 23, 1,100,119,101,108,116, 18, 8, 3, 21, 1,100, + 111,116,104, 39, 8, 3, 21, 1,100,105,101,100, 47, 12, 3, 29, 1,100,101, + 112, 97,114,116,101,100, 26, 10, 3, 25, 1, 99,117, 98,105,116,115, 33, 9, + 3, 23, 1, 99,104,105,108,100, 42, 7, 3, 19, 1, 99, 97,110, 4, 11, 3, + 27, 1, 98,101,116,119,101,101,110, 10, 9, 3, 23, 1, 98,101,103, 97,116, + 19, 8, 3, 21, 1, 98,101, 97,114, 29, 7, 3, 19, 1, 97,114,107, 13, 9, + 3, 23, 1, 97,110,103,101,114, 5, 9, 3, 23, 1, 97,110,103,101,108, 44, + 9, 3, 23, 1, 97, 98,111,118,101, 22, 10, 0, 0, 0, 9, 1,171, 0, 1, + 247, 1,238, 1,230, 1,221, 1,211, 1,202, 1,191, 1,181, 1,171, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 3, 23, 1,119,114, 97,116,104, 50, 9, 3, 23, 1,119,111,114,107,115, + 2, 10, 3, 25, 1,119,105,115,100,111,109, 6, 8, 3, 21, 1,119,105,110, + 101, 12, 9, 3, 23, 1,119,104,105,108,101, 31, 8, 3, 21, 1,119, 97,121, + 115, 41, 7, 3, 19, 1,119, 97,114, 21, 8, 3, 21, 1,119, 97,108,107, 34, + 8, 3, 23, 9,116,114,117,116,104, 13, 0, 0, 0, 5, 0, 84, 0, 1, 78, + 0,249, 0,177, 1,163, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 19, + 7, 21, 19, 19, 8,129, 33,118,105,101,119,118, 50, 49,118, 50, 49, 67, 82, + 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 50, 49, 40, 97, 44, 98, 44, 99, + 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, + 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 79, 82, 68, 69, + 82, 32, 66, 89, 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 70, 17, 6, 21, + 19, 19, 8,121,118,105,101,119,118, 53, 48,118, 53, 48, 67, 82, 69, 65, 84, + 69, 32, 86, 73, 69, 87, 32,118, 53, 48, 40, 97, 44, 98, 41, 32, 65, 83, 32, + 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 32, 70, 82, 79, 77, 32,116, 53, 32, + 87, 72, 69, 82, 69, 32, 97, 60, 62, 50, 53, 83, 16, 7, 21, 19, 19, 8,129, + 17,118,105,101,119,118, 52, 48,118, 52, 48, 67, 82, 69, 65, 84, 69, 32, 86, + 73, 69, 87, 32,118, 52, 48, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, + 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, + 32, 70, 82, 79, 77, 32,116, 52, 32, 87, 72, 69, 82, 69, 32, 97, 60, 62, 50, + 53, 83, 15, 7, 21, 19, 19, 8,129, 17,118,105,101,119,118, 51, 48,118, 51, + 48, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 51, 48, 40, 97, 44, + 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, + 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 51, 32, 87, + 72, 69, 82, 69, 32, 97, 60, 62, 50, 53, 91, 18, 7, 21, 19, 19, 8,129, 33, + 118,105,101,119,118, 49, 49,118, 49, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, + 69, 87, 32,118, 49, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, + 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, + 70, 82, 79, 77, 32,116, 49, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, 32, + 76, 73, 77, 73, 84, 32, 49, 48, 13, 1,163, 0, 4, 0, 40, 0, 1, 70, 0, + 233, 0,152, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 23, 7, 21, 19, 19, 8,129, 71, + 118,105,101,119,118, 49, 50,118, 49, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, + 69, 87, 32,118, 49, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, + 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, 41, 44, 32, + 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109, + 105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 71, 82, + 79, 85, 80, 32, 66, 89, 32, 53, 79, 22, 7, 21, 19, 19, 8,129, 9,118,105, + 101,119,118, 53, 49,118, 53, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, + 32,118, 53, 49, 40, 97, 44, 98, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, + 32, 97, 44, 98, 32, 70, 82, 79, 77, 32,116, 53, 32, 79, 82, 68, 69, 82, 32, + 66, 89, 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 91, 21, 7, 21, 19, 19, + 8,129, 33,118,105,101,119,118, 52, 49,118, 52, 49, 67, 82, 69, 65, 84, 69, + 32, 86, 73, 69, 87, 32,118, 52, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, + 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, + 44,101, 32, 70, 82, 79, 77, 32,116, 52, 32, 79, 82, 68, 69, 82, 32, 66, 89, + 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 91, 20, 7, 21, 19, 19, 8,129, + 33,118,105,101,119,118, 51, 49,118, 51, 49, 67, 82, 69, 65, 84, 69, 32, 86, + 73, 69, 87, 32,118, 51, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, + 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, + 32, 70, 82, 79, 77, 32,116, 51, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, + 32, 76, 73, 77, 73, 84, 32, 49, 48, 0, 0, 0, 93, 19, 19, 8,129, 33,118, + 105,101,119,118, 50, 49,118, 50, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, + 87, 32,118, 50, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, + 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, + 82, 79, 77, 32,116, 50, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, 32, 76, + 73, 77, 73, 84, 32, 49, 48, 13, 0, 0, 0, 3, 0, 66, 0, 1,107, 0,214, + 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 17, 26, + 7, 21, 19, 19, 8,130, 13,118,105,101,119,118, 52, 50,118, 52, 50, 67, 82, + 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 52, 50, 40, 97, 44, 98, 44, 99, + 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115, + 117,109, 40, 97, 41, 44, 32, 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110, + 116, 40, 42, 41, 44, 32,109,105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, + 77, 32,116, 52, 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, + 32, 72, 65, 86, 73, 78, 71, 32,109,105,110, 40,100, 41, 60, 51, 48, 32, 79, + 82, 68, 69, 82, 32, 66, 89, 32, 51, 44, 32, 49,129, 18, 25, 7, 21, 19, 19, + 8,130, 15,118,105,101,119,118, 51, 50,118, 51, 50, 67, 82, 69, 65, 84, 69, + 32, 86, 73, 69, 87, 32,118, 51, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, + 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, + 41, 44, 32, 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, + 44, 32,109,105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 51, + 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, 32, 72, 65, 86, + 73, 78, 71, 32, 99,111,117,110,116, 40, 42, 41, 62, 49, 32, 79, 82, 68, 69, + 82, 32, 66, 89, 32, 51, 44, 32, 49,129, 18, 24, 7, 21, 19, 19, 8,130, 15, + 118,105,101,119,118, 50, 50,118, 50, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, + 69, 87, 32,118, 50, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, + 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, 41, 44, 32, + 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109, + 105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 71, 82, + 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, 32, 72, 65, 86, 73, 78, 71, + 32, 99,111,117,110,116, 40, 42, 41, 62, 49, 32, 79, 82, 68, 69, 82, 32, 66, + 89, 32, 51, 44, 32, 49, 13, 1,108, 0, 3, 0, 83, 0, 0,225, 0, 83, 1, + 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 11, 28, 7, 21, 19, + 19, 8,130, 1,118,105,101,119,118, 49, 51,118, 49, 51, 67, 82, 69, 65, 84, + 69, 32, 86, 73, 69, 87, 32,118, 49, 51, 40, 97, 44, 98, 44, 99, 44,100, 44, + 101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, + 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 10, 32, 32, 85, 78, 73, + 79, 78, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, + 32, 70, 82, 79, 77, 32,116, 50, 10, 32, 32, 85, 78, 73, 79, 78, 32, 83, 69, + 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, + 32,116, 51,129, 8, 27, 7, 21, 19, 19, 8,129,123,118,105,101,119,118, 53, + 50,118, 53, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 53, 50, + 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, + 76, 69, 67, 84, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109,105,110, 40, + 98, 41, 44, 32,115,117, 98,115,116,114, 40, 98, 44, 49, 44, 49, 41, 44, 32, + 109,105,110, 40, 97, 41, 44, 32,109, 97,120, 40, 97, 41, 32, 70, 82, 79, 77, + 32,116, 53, 10, 32, 32, 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 51, 32, 79, + 82, 68, 69, 82, 32, 66, 89, 32, 49, 0, 0, 0, 28, 21, 19, 19, 8,130, 13, + 118,105,101,119,118, 52, 50,118, 52, 50, 67, 82, 69, 65, 84, 69, 32, 86,118, + 29, 7, 21, 19, 19, 8,129, 87,118,105,101,119,118, 50, 51,118, 50, 51, 67, + 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 50, 51, 40, 97, 44, 98, 44, + 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32, + 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 10, 32, + 32, 69, 88, 67, 69, 80, 84, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, + 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 87, 72, 69, 82, 69, + 32, 98, 60, 50, 53, 13, 0, 0, 0, 3, 0, 40, 0, 1,134, 1, 12, 0, 40, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,129, 97, 32, 7, 21, 19, 19, 8,131, 45,118,105, + 101,119,118, 54, 50,118, 54, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, + 32,118, 54, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, + 32, 32, 83, 69, 76, 69, 67, 84, 32,116, 49, 46, 97, 44,116, 50, 46, 98, 44, + 116, 51, 46, 99, 44,116, 52, 46,100, 44,116, 53, 46, 98, 10, 32, 32, 32, 32, + 70, 82, 79, 77, 32,116, 49, 32, 74, 79, 73, 78, 32,116, 50, 32, 79, 78, 32, + 40,116, 49, 46, 97, 61,116, 50, 46, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 74, 79, 73, 78, 32,116, 51, 32, 79, 78, 32, 40,116, 49, + 46, 97, 61,116, 51, 46, 97, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 74, 79, 73, 78, 32,116, 52, 32, 79, 78, 32, 40,116, 52, 46, 98, 61, + 116, 51, 46, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 76, + 69, 70, 84, 32, 74, 79, 73, 78, 32,116, 53, 32, 79, 78, 32, 40,116, 53, 46, + 97, 61,116, 49, 46, 99, 41,120, 31, 7, 21, 19, 19, 8,129, 91,118,105,101, + 119,118, 54, 49,118, 54, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32, + 118, 54, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, + 32, 83, 69, 76, 69, 67, 84, 32,116, 50, 46, 97, 44,116, 51, 46, 98, 44,116, + 50, 46, 99, 44,116, 51, 46,100, 44,116, 50, 46,101, 10, 32, 32, 32, 32, 70, + 82, 79, 77, 32,116, 50, 32, 76, 69, 70, 84, 32, 74, 79, 73, 78, 32,116, 51, + 32, 79, 78, 32, 40,116, 50, 46, 97, 61,116, 51, 46, 97, 41,120, 30, 7, 21, + 19, 19, 8,129, 91,118,105,101,119,118, 54, 48,118, 54, 48, 67, 82, 69, 65, + 84, 69, 32, 86, 73, 69, 87, 32,118, 54, 48, 40, 97, 44, 98, 44, 99, 44,100, + 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,116, 49, 46, + 97, 44,116, 50, 46, 98, 44,116, 49, 46, 99, 44,116, 50, 46,100, 44,116, 49, + 46,101, 10, 32, 32, 32, 32, 70, 82, 79, 77, 32,116, 49, 32, 76, 69, 70, 84, + 32, 74, 79, 73, 78, 32,116, 50, 32, 79, 78, 32, 40,116, 49, 46, 97, 61,116, + 50, 46, 98, 41, 13, 0, 0, 0, 1, 1, 73, 0, 1, 73, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 52, 33, 7, 21, 19, 19, 8,130, + 83,118,105,101,119,118, 55, 48,118, 55, 48, 67, 82, 69, 65, 84, 69, 32, 86, + 73, 69, 87, 32,118, 55, 48, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, + 65, 83, 10, 32, 32, 87, 73, 84, 72, 32, 82, 69, 67, 85, 82, 83, 73, 86, 69, + 32, 99, 48, 40,120, 41, 32, 65, 83, 32, 40, 86, 65, 76, 85, 69, 83, 40, 49, + 41, 32, 85, 78, 73, 79, 78, 32, 65, 76, 76, 32, 83, 69, 76, 69, 67, 84, 32, + 120, 43, 49, 32, 70, 82, 79, 77, 32, 99, 48, 32, 87, 72, 69, 82, 69, 32,120, + 60, 57, 41, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,120, 44, 32, 98, 44, 32, + 99, 44, 32,100, 44, 32,101, 32, 70, 82, 79, 77, 32, 99, 48, 32, 74, 79, 73, + 78, 32,116, 49, 32, 79, 78, 32, 40,116, 49, 46, 97, 61, 53, 48, 45, 99, 48, + 46,120, 41, +}; + diff --git a/test/optfuzz-db01.txt b/test/optfuzz-db01.txt new file mode 100644 index 0000000000..d9eef9320d --- /dev/null +++ b/test/optfuzz-db01.txt @@ -0,0 +1,142 @@ +-- Run this script through the sqlite3 command-line shell in order to generate +-- a database file containing lots of data for testing purposes. +-- +-- This script assumes that the "bin2c" program is available on ones $PATH. +-- The "bin2c" program reads a binary file and outputs C-code that creates +-- an array of bytes holding the content of that file. +-- +-- This script is designed to create many tables and views all having +-- 5 columns, "a" through "e", and with a variety of integers, short strings, +-- and NULL values. +-- +.open -new testdb01.db +PRAGMA page_size=512; +BEGIN; +CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT, d INT, e INT); +WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<50) +INSERT INTO t1(a,b,c,d,e) SELECT x,abs(random()%51), + abs(random()%100), abs(random()%51), abs(random()%100) FROM c; +CREATE TABLE t2(a INT, b INT, c INT,d INT,e INT,PRIMARY KEY(b,a))WITHOUT ROWID; +INSERT INTO t2 SELECT * FROM t1; +CREATE TABLE t3(a,b,c,d,e); +INSERT INTO t3 SELECT a,b,c,d,e FROM t1 ORDER BY random() LIMIT 5; +INSERT INTO t3 SELECT null,b,c,d,e FROM t1 ORDER BY random() LIMIT 5; +INSERT INTO t3 SELECT a,null,c,d,e FROM t1 ORDER BY random() LIMIT 5; +INSERT INTO t3 SELECT a,b,null,d,e FROM t1 ORDER BY random() LIMIT 5; +INSERT INTO t3 SELECT a,b,c,null,e FROM t1 ORDER BY random() LIMIT 5; +INSERT INTO t3 SELECT a,b,c,d,null FROM t1 ORDER BY random() LIMIT 5; +INSERT INTO t3 SELECT null,null,null,null,null FROM t1 LIMIT 5; +CREATE INDEX t3x1 ON t3(a,b,c,d,e); +CREATE TABLE t4(a INT UNIQUE NOT NULL, b INT UNIQUE NOT NULL,c,d,e); +INSERT OR IGNORE INTO t4 SELECT a,b,c,d,e FROM t3; +CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT UNIQUE,c,d,e); +INSERT INTO t5(b) VALUES + ('truth'), + ('works'), + ('offer'), + ('can'), + ('anger'), + ('wisdom'), + ('send'), + ('though'), + ('save'), + ('between'), + ('some'), + ('wine'), + ('ark'), + ('smote'), + ('therein'), + ('shew'), + ('morning'), + ('dwelt'), + ('begat'), + ('nothing'), + ('war'), + ('above'), + ('known'), + ('sacrifice'), + ('tell'), + ('departed'), + ('thyself'), + ('places'), + ('bear'), + ('part'), + ('while'), + ('gone'), + ('cubits'), + ('walk'), + ('long'), + ('near'), + ('serve'), + ('fruit'), + ('doth'), + ('poor'), + ('ways'), + ('child'), + ('temple'), + ('angel'), + ('inhabitants'), + ('oil'), + ('died'), + ('six'), + ('tree'), + ('wrath'); +UPDATE t1 SET e=(SELECT b FROM t5 WHERE t5.a=(t1.e%51)); +UPDATE t5 SET (c,d,e) = + (SELECT c,d,e FROM t1 WHERE t1.a=abs(t5.a+random()/100)%50+1); +UPDATE t2 SET e=(SELECT b FROM t5 WHERE t5.a=(t2.e%51)); +UPDATE t3 SET e=(SELECT b FROM t5 WHERE t5.a=t3.e); +CREATE INDEX t1e ON t1(e); +CREATE INDEX t2ed ON t2(e,d); +CREATE VIEW v00(a,b,c,d,e) AS SELECT 1,1,1,1,'one'; +CREATE VIEW v10(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t1 WHERE a<>25; +CREATE VIEW v20(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t2 WHERE a<>25; +CREATE VIEW v30(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t3 WHERE a<>25; +CREATE VIEW v40(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t4 WHERE a<>25; +CREATE VIEW v50(a,b) AS SELECT a,b FROM t5 WHERE a<>25; +CREATE VIEW v11(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t1 ORDER BY b LIMIT 10; +CREATE VIEW v21(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t2 ORDER BY b LIMIT 10; +CREATE VIEW v31(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t3 ORDER BY b LIMIT 10; +CREATE VIEW v41(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t4 ORDER BY b LIMIT 10; +CREATE VIEW v51(a,b) AS SELECT a,b FROM t5 ORDER BY b LIMIT 10; +CREATE VIEW v12(a,b,c,d,e) AS + SELECT sum(a), avg(b), count(*), min(d), e FROM t1 GROUP BY 5; +CREATE VIEW v22(a,b,c,d,e) AS + SELECT sum(a), avg(b), count(*), min(d), e FROM t2 GROUP BY 5 + HAVING count(*)>1 ORDER BY 3, 1; +CREATE VIEW v32(a,b,c,d,e) AS + SELECT sum(a), avg(b), count(*), min(d), e FROM t3 GROUP BY 5 + HAVING count(*)>1 ORDER BY 3, 1; +CREATE VIEW v42(a,b,c,d,e) AS + SELECT sum(a), avg(b), count(*), min(d), e FROM t4 GROUP BY 5 + HAVING min(d)<30 ORDER BY 3, 1; +CREATE VIEW v52(a,b,c,d,e) AS + SELECT count(*), min(b), substr(b,1,1), min(a), max(a) FROM t5 + GROUP BY 3 ORDER BY 1; + +CREATE VIEW v13(a,b,c,d,e) AS + SELECT a,b,c,d,e FROM t1 + UNION SELECT a,b,c,d,e FROM t2 + UNION SELECT a,b,c,d,e FROM t3; +CREATE VIEW v23(a,b,c,d,e) AS + SELECT a,b,c,d,e FROM t1 + EXCEPT SELECT a,b,c,d,e FROM t1 WHERE b<25; + +CREATE VIEW v60(a,b,c,d,e) AS + SELECT t1.a,t2.b,t1.c,t2.d,t1.e + FROM t1 LEFT JOIN t2 ON (t1.a=t2.b); +CREATE VIEW v61(a,b,c,d,e) AS + SELECT t2.a,t3.b,t2.c,t3.d,t2.e + FROM t2 LEFT JOIN t3 ON (t2.a=t3.a); +CREATE VIEW v62(a,b,c,d,e) AS + SELECT t1.a,t2.b,t3.c,t4.d,t5.b + FROM t1 JOIN t2 ON (t1.a=t2.b) + JOIN t3 ON (t1.a=t3.a) + JOIN t4 ON (t4.b=t3.b) + LEFT JOIN t5 ON (t5.a=t1.c); +CREATE VIEW v70(a,b,c,d,e) AS + WITH RECURSIVE c0(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c0 WHERE x<9) + SELECT x, b, c, d, e FROM c0 JOIN t1 ON (t1.a=50-c0.x); +COMMIT; +VACUUM; +.shell bin2c testdb01.db diff --git a/test/optfuzz.c b/test/optfuzz.c new file mode 100644 index 0000000000..1992acac3a --- /dev/null +++ b/test/optfuzz.c @@ -0,0 +1,309 @@ +/* +** 2018-03-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This program attempts to verify the correctness of the SQLite query +** optimizer by fuzzing. +** +** The input is an SQL script, presumably generated by a fuzzer. The +** argument is the name of the input. If no files are named, standard +** input is read. +** +** The SQL script is run twice, once with optimization enabled, and again +** with optimization disabled. If the output is not equivalent, an error +** is printed and the program returns non-zero. +*/ + +/* Include the SQLite amalgamation, after making appropriate #defines. +*/ +#define SQLITE_THREADSAFE 0 +#define SQLITE_OMIT_LOAD_EXTENSION 1 +#define SQLITE_ENABLE_DESERIALIZE 1 +#include "sqlite3.c" + +/* Content of the read-only test database */ +#include "optfuzz-db01.c" + +/* +** Prepare a single SQL statement. Panic if anything goes wrong +*/ +static sqlite3_stmt *prepare_sql(sqlite3 *db, const char *zFormat, ...){ + char *zSql; + int rc; + sqlite3_stmt *pStmt = 0; + va_list ap; + + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc ){ + printf("Error: %s\nSQL: %s\n", + sqlite3_errmsg(db), zSql); + exit(1); + } + sqlite3_free(zSql); + return pStmt; +} + +/* +** Run SQL. Panic if anything goes wrong +*/ +static void run_sql(sqlite3 *db, const char *zFormat, ...){ + char *zSql; + int rc; + char *zErr = 0; + va_list ap; + + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + rc = sqlite3_exec(db, zSql, 0, 0, &zErr); + if( rc || zErr ){ + printf("Error: %s\nsqlite3_errmsg: %s\nSQL: %s\n", + zErr, sqlite3_errmsg(db), zSql); + exit(1); + } + sqlite3_free(zSql); +} + +/* +** Run one or more SQL statements contained in zSql against database dbRun. +** Store the input in database dbOut. +*/ +static int optfuzz_exec( + sqlite3 *dbRun, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + sqlite3 *dbOut, /* Store results in this database */ + const char *zOutTab, /* Store results in this table of dbOut */ + int *pnStmt, /* Write the number of statements here */ + int *pnRow, /* Write the number of rows here */ + int bTrace /* Print query results if true */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zLeftover; /* Tail of unprocessed SQL */ + sqlite3_stmt *pStmt = 0; /* The current SQL statement */ + sqlite3_stmt *pIns = 0; /* Statement to insert into dbOut */ + const char *zCol; /* Single column value */ + int nCol; /* Number of output columns */ + char zLine[4000]; /* Complete row value */ + + run_sql(dbOut, "BEGIN"); + run_sql(dbOut, "CREATE TABLE IF NOT EXISTS staging(x TEXT)"); + run_sql(dbOut, "CREATE TABLE IF NOT EXISTS \"%w\"(x TEXT)", zOutTab); + pIns = prepare_sql(dbOut, "INSERT INTO staging(x) VALUES(?1)"); + *pnRow = *pnStmt = 0; + while( rc==SQLITE_OK && zSql && zSql[0] ){ + zLeftover = 0; + rc = sqlite3_prepare_v2(dbRun, zSql, -1, &pStmt, &zLeftover); + zSql = zLeftover; + assert( rc==SQLITE_OK || pStmt==0 ); + if( rc!=SQLITE_OK ){ + printf("Error with [%s]\n%s\n", zSql, sqlite3_errmsg(dbRun)); + break; + } + if( !pStmt ) continue; + (*pnStmt)++; + nCol = sqlite3_column_count(pStmt); + run_sql(dbOut, "DELETE FROM staging;"); + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + int i, j; + for(i=j=0; i=sizeof(zLine)-100 ){ + printf("Excessively long output line: %d bytes\n" ,j); + exit(1); + } + if( bTrace ){ + printf("%s\n", zLine); + } + (*pnRow)++; + sqlite3_bind_text(pIns, 1, zLine, j, SQLITE_TRANSIENT); + rc = sqlite3_step(pIns); + assert( rc==SQLITE_DONE ); + rc = sqlite3_reset(pIns); + } + run_sql(dbOut, + "INSERT INTO \"%w\"(x) VALUES('### %q ###')", + zOutTab, sqlite3_sql(pStmt) + ); + run_sql(dbOut, + "INSERT INTO \"%w\"(x) SELECT group_concat(x,char(10))" + " FROM (SELECT x FROM staging ORDER BY x)", + zOutTab + ); + run_sql(dbOut, "COMMIT"); + sqlite3_finalize(pStmt); + pStmt = 0; + } + sqlite3_finalize(pStmt); + sqlite3_finalize(pIns); + return rc; +} + +/* +** Read the content of file zName into memory obtained from sqlite3_malloc64() +** and return a pointer to the buffer. The caller is responsible for freeing +** the memory. +** +** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes +** read. +** +** For convenience, a nul-terminator byte is always appended to the data read +** from the file before the buffer is returned. This byte is not included in +** the final value of (*pnByte), if applicable. +** +** NULL is returned if any error is encountered. The final value of *pnByte +** is undefined in this case. +*/ +static char *readFile(const char *zName, int *pnByte){ + FILE *in = fopen(zName, "rb"); + long nIn; + size_t nRead; + char *pBuf; + if( in==0 ) return 0; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc64( nIn+1 ); + if( pBuf==0 ) return 0; + nRead = fread(pBuf, nIn, 1, in); + fclose(in); + if( nRead!=1 ){ + sqlite3_free(pBuf); + return 0; + } + pBuf[nIn] = 0; + if( pnByte ) *pnByte = nIn; + return pBuf; +} + +int main(int argc, char **argv){ + int nIn = 0; /* Number of input files */ + char **azIn = 0; /* Names of input files */ + sqlite3 *dbOut = 0; /* Database to hold results */ + sqlite3 *dbRun = 0; /* Database used for tests */ + int bTrace = 0; /* Show query results */ + int bShowValid = 0; /* Just list inputs that are valid SQL */ + int nRow, nStmt; /* Number of rows and statements */ + int i, rc; + + for(i=1; i -#include +#if !defined(_MSC_VER) +# include +#endif #include #include #include "sqlite3.h" +#if defined(_MSC_VER) +typedef unsigned char uint8_t; +#endif + /* Global debugging settings. OSS-Fuzz will have all debugging turned ** off. But if LLVMFuzzerTestOneInput() is called interactively from ** the ossshell utility program, then these flags might be set. @@ -160,6 +166,9 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { /* Run the SQL. The sqlite_exec() interface expects a zero-terminated ** string, so make a copy. */ zSql = sqlite3_mprintf("%.*s", (int)size, data); +#ifndef SQLITE_OMIT_COMPLETE + sqlite3_complete(zSql); +#endif sqlite3_exec(cx.db, zSql, exec_handler, (void*)&execCnt, &zErrMsg); /* Show any errors */ diff --git a/test/ossshell.c b/test/ossshell.c index 00cc3391c8..54849f97f6 100644 --- a/test/ossshell.c +++ b/test/ossshell.c @@ -6,12 +6,18 @@ ** command line and passes them one by one into ossfuzz.c. */ #include -#include +#if !defined(_MSC_VER) +# include +#endif #include #include #include #include "sqlite3.h" +#if defined(_MSC_VER) +typedef unsigned char uint8_t; +#endif + /* ** The entry point in ossfuzz.c that this routine will be calling */ diff --git a/test/pager1.test b/test/pager1.test index 8451e0b3d2..1d56fad30b 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -17,6 +17,11 @@ source $testdir/malloc_common.tcl source $testdir/wal_common.tcl set testprefix pager1 +if {[atomic_batch_write test.db]} { + finish_test + return +} + # Do not use a codec for tests in this file, as the database file is # manipulated directly using tcl scripts (using the [hexio_write] command). # @@ -1144,7 +1149,7 @@ do_test pager1-5.5.1 { PRAGMA journal_mode = PERSIST; CREATE TABLE t3(a, b); INSERT INTO t3 SELECT randomblob(1500), randomblob(1500) FROM t1; - UPDATE t3 SET b = randomblob(1500); + UPDATE t3 SET b = randomblob(1501); } expr [file size test.db-journal] > 15000 } {1} diff --git a/test/pager3.test b/test/pager3.test index 23435a79b7..e815f2788b 100644 --- a/test/pager3.test +++ b/test/pager3.test @@ -16,6 +16,10 @@ source $testdir/lock_common.tcl source $testdir/malloc_common.tcl source $testdir/wal_common.tcl +if {[atomic_batch_write test.db]} { + finish_test + return +} foreach {tn sql res j} { 1 "PRAGMA journal_mode = DELETE" delete 0 diff --git a/test/pagerfault.test b/test/pagerfault.test index 392c1a2b98..3006dad7cc 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -1203,12 +1203,14 @@ do_faultsim_test pagerfault-26 -prep { set contents [db eval {SELECT * FROM t1}] if {$contents != "1 2"} { error "Bad database contents ($contents)" } - set sz [file size test.db] - if {$testrc!=0 && $sz!=1024*3 && $sz!=4096*3} { - error "Expected file size to be 3072 or 12288 bytes - actual size $sz bytes" - } - if {$testrc==0 && $sz!=4096*3} { - error "Expected file size to be 12288 bytes - actual size $sz bytes" + if {[atomic_batch_write test.db]==0} { + set sz [file size test.db] + if {$testrc!=0 && $sz!=1024*3 && $sz!=4096*3} { + error "Expected file size 3072 or 12288 bytes - actual size $sz bytes" + } + if {$testrc==0 && $sz!=4096*3} { + error "Expected file size to be 12288 bytes - actual size $sz bytes" + } } } diff --git a/test/permutations.test b/test/permutations.test index bcd06c14b7..4940e34899 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -48,6 +48,13 @@ proc test_suite {name args} { set options([lindex $o 0]) $v } + # Transform "-presql" into a "dbconfig" script + # + if {[info exists options(-presql)]} { + append options(-dbconfig) "\n\$::dbhandle eval { $options(-presql) }" + unset options(-presql) + } + set ::testspec($name) [array get options] lappend ::testsuitelist $name } @@ -86,9 +93,10 @@ proc test_set {args} { # set alltests [list] foreach f [glob $testdir/*.test] { lappend alltests [file tail $f] } -foreach f [glob -nocomplain \ - $testdir/../ext/rtree/*.test \ +foreach f [glob -nocomplain \ + $testdir/../ext/rtree/*.test \ $testdir/../ext/fts5/test/*.test \ + $testdir/../ext/expert/*.test \ $testdir/../ext/lsm1/test/*.test \ ] { lappend alltests $f @@ -104,7 +112,7 @@ set alltests [test_set $alltests -exclude { all.test async.test quick.test veryquick.test memleak.test permutations.test soak.test fts3.test mallocAll.test rtree.test full.test extraquick.test - session.test + session.test rbu.test }] set allquicktests [test_set $alltests -exclude { @@ -121,7 +129,7 @@ set allquicktests [test_set $alltests -exclude { vtab_err.test walslow.test walcrash.test walcrash3.test walthread.test rtree3.test indexfault.test securedel2.test sort3.test sort4.test fts4growth.test fts4growth2.test - bigsort.test rbu.test walprotocol.test mmap4.test fuzzer2.test + bigsort.test walprotocol.test mmap4.test fuzzer2.test walcrash2.test e_fkey.test backup.test fts4merge.test fts4merge2.test fts4merge4.test fts4check.test @@ -194,7 +202,7 @@ test_suite "valgrind" -prefix "" -description { } -files [ test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* wal.test \ shell*.test crash8.test atof1.test selectG.test \ - tkt-fc62af4523.test numindex1.test + tkt-fc62af4523.test numindex1.test corruptK.test ] -initialize { set ::G(valgrind) 1 } -shutdown { @@ -282,6 +290,12 @@ test_suite "fts5-light" -prefix "" -description { -exclude *corrupt* *fault* *big* *fts5aj* ] +test_suite "window" -prefix "" -description { + All window function related tests . +} -files [ + test_set [glob -nocomplain $::testdir/window*.test] +] + test_suite "lsm1" -prefix "" -description { All LSM1 tests. } -files [glob -nocomplain $::testdir/../ext/lsm1/test/*.test] @@ -455,33 +469,31 @@ lappend ::testsuitelist xxx # Define the permutation test suites: # -# Run some tests using pre-allocated page and scratch blocks. +# Run some tests using pre-allocated page blocks. # # mmap1.test is excluded because a good number of its tests depend on # the page-cache being larger than the database. But this permutation # causes the effective limit on the page-cache to be just 24 pages. # test_suite "memsubsys1" -description { - Tests using pre-allocated page and scratch blocks + Tests using pre-allocated page blocks } -files [ test_set $::allquicktests -exclude ioerr5.test malloc5.test mmap1.test ] -initialize { test_set_config_pagecache 4096 24 catch {db close} sqlite3_shutdown - sqlite3_config_scratch 25000 1 sqlite3_initialize autoinstall_test_functions } -shutdown { test_restore_config_pagecache catch {db close} sqlite3_shutdown - sqlite3_config_scratch 0 0 sqlite3_initialize autoinstall_test_functions } -# Run some tests using pre-allocated page and scratch blocks. This time +# Run some tests using pre-allocated page blocks. This time # the allocations are too small to use in most cases. # # Both ioerr5.test and malloc5.test are excluded because they test the @@ -489,21 +501,19 @@ test_suite "memsubsys1" -description { # This functionality is disabled if a pre-allocated page block is provided. # test_suite "memsubsys2" -description { - Tests using small pre-allocated page and scratch blocks + Tests using small pre-allocated page blocks } -files [ test_set $::allquicktests -exclude ioerr5.test malloc5.test ] -initialize { test_set_config_pagecache 512 5 catch {db close} sqlite3_shutdown - sqlite3_config_scratch 1000 1 sqlite3_initialize autoinstall_test_functions } -shutdown { test_restore_config_pagecache catch {db close} sqlite3_shutdown - sqlite3_config_scratch 0 0 sqlite3_initialize autoinstall_test_functions } @@ -551,21 +561,12 @@ test_suite "singlethread" -description { test_suite "nomutex" -description { Tests run with the SQLITE_OPEN_MULTITHREADED flag passed to sqlite3_open(). } -initialize { - rename sqlite3 sqlite3_nomutex - proc sqlite3 {args} { - if {[string range [lindex $args 0] 0 0] ne "-"} { - lappend args -fullmutex 0 -nomutex 1 - } - uplevel [concat sqlite3_nomutex $args] - } + set ::G(perm:sqlite3_args) [list -fullmutex 0 -nomutex 1] } -files { delete.test delete2.test insert.test rollback.test select1.test select2.test trans.test update.test vacuum.test types.test types2.test types3.test -} -shutdown { - rename sqlite3 {} - rename sqlite3_nomutex sqlite3 -} +} # Run some tests in SQLITE_CONFIG_MULTITHREAD mode. # @@ -594,20 +595,11 @@ test_suite "multithread" -description { test_suite "fullmutex" -description { Tests run in SQLITE_OPEN_FULLMUTEX mode } -initialize { - rename sqlite3 sqlite3_fullmutex - proc sqlite3 {args} { - if {[string range [lindex $args 0] 0 0] ne "-"} { - lappend args -nomutex 0 -fullmutex 1 - } - uplevel [concat sqlite3_fullmutex $args] - } + set ::G(perm:sqlite3_args) [list -nomutex 0 -fullmutex 1] } -files { delete.test delete2.test insert.test rollback.test select1.test select2.test trans.test update.test vacuum.test types.test types2.test types3.test -} -shutdown { - rename sqlite3 {} - rename sqlite3_fullmutex sqlite3 } # Run some tests using the "onefile" demo. @@ -615,19 +607,10 @@ test_suite "fullmutex" -description { test_suite "onefile" -description { Run some tests using the "test_onefile.c" demo } -initialize { - rename sqlite3 sqlite3_onefile - proc sqlite3 {args} { - if {[string range [lindex $args 0] 0 0] ne "-"} { - lappend args -vfs fs - } - uplevel [concat sqlite3_onefile $args] - } + set ::G(perm:sqlite3_args) [list -vfs fs] } -files { conflict.test insert.test insert2.test insert3.test rollback.test select1.test select2.test select3.test -} -shutdown { - rename sqlite3 {} - rename sqlite3_onefile sqlite3 } # Run some tests using UTF-16 databases. @@ -929,17 +912,8 @@ ifcapable threadsafe { test_suite "safe_append" -description { Run some tests on a SAFE_APPEND file-system. } -initialize { - rename sqlite3 sqlite3_safeappend - proc sqlite3 {args} { - if {[string range [lindex $args 0] 0 0] ne "-"} { - lappend args -vfs devsym - } - uplevel [concat sqlite3_safeappend $args] - } + set ::G(perm:sqlite3_args) [list -vfs devsym] sqlite3_simulate_device -char safe_append -} -shutdown { - rename sqlite3 {} - rename sqlite3_shutdown sqlite3 } -files [ test_set $::allquicktests shared_err.test -exclude async3.test ] @@ -1069,13 +1043,33 @@ test_suite "no_optimization" -description { test_suite "prepare" -description { Run tests with the db connection using sqlite3_prepare() instead of _v2(). } -dbconfig { - db_use_legacy_prepare $::dbhandle 1 + $::dbhandle version -use-legacy-prepare 1 #$::dbhandle cache size 0 } -files [ test_set $allquicktests -exclude *malloc* *ioerr* *fault* \ stmtvtab1.test index9.test ] +test_suite "sorterref" -prefix "" -description { + Run the "veryquick" test suite with SQLITE_CONFIG_SORTERREF_SIZE set + to 0 so that sorter-references are used whenever possible. +} -files [ + test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \ + *fts5corrupt* *fts5big* *fts5aj* +] -initialize { + catch {db close} + sqlite3_shutdown + sqlite3_config_sorterref 0 + sqlite3_initialize + autoinstall_test_functions +} -shutdown { + catch {db close} + sqlite3_shutdown + sqlite3_config_sorterref -1 + sqlite3_initialize + autoinstall_test_functions +} + # End of tests ############################################################################# @@ -1086,16 +1080,20 @@ test_suite "prepare" -description { # -description TITLE # -initialize SCRIPT # -shutdown SCRIPT -# -presql SQL # -files LIST-OF-FILES # -prefix NAME +# -dbconfig SCRIPT # proc run_tests {name args} { + set options(-initialize) "" + set options(-shutdown) "" + set options(-prefix) "" + set options(-dbconfig) "" + array set options $args set ::G(perm:name) $name set ::G(perm:prefix) $options(-prefix) - set ::G(perm:presql) $options(-presql) set ::G(isquick) 1 set ::G(perm:dbconfig) $options(-dbconfig) @@ -1104,11 +1102,12 @@ proc run_tests {name args} { if {[file tail $file] == $file} { set file [file join $::testdir $file] } slave_test_file $file uplevel $options(-shutdown) + + unset -nocomplain ::G(perm:sqlite3_args) } unset ::G(perm:name) unset ::G(perm:prefix) - unset ::G(perm:presql) unset ::G(perm:dbconfig) } @@ -1123,19 +1122,29 @@ proc help {} { puts "Usage: $::argv0 TESTSUITE ?TESTFILE?" puts "" puts "Available test-suites are:" + + set iPos 0 foreach k $::testsuitelist { - if {[info exists ::testspec($k)]==0} { - puts " ----------------------------------------" - puts "" - } else { - array set o $::testspec($k) - puts "Test suite: \"$k\"" - set d [string trim $o(-description)] - set d [regsub {\n *} $d "\n "] - puts " $d" - puts "" + if {[info exists ::testspec($k)]} { + switch $iPos { + 0 { + puts "" + puts -nonewline " [format %-30s $k]" + } + + 1 { + puts -nonewline [format %-30s $k] + } + + 2 { + puts -nonewline $k + } + } + + set iPos [expr (($iPos+1) % 3)] } } + puts "" exit -1 } @@ -1144,11 +1153,35 @@ if {[file tail $argv0] == "permutations.test"} { if {[llength $argv]==0} { help } else { + + # See if the first argument is a named test-suite. + # set suite [file tail [lindex $argv 0]] - if {[info exists ::testspec($suite)]==0} help + if {[info exists ::testspec($suite)]} { + set S $::testspec($suite) + set i 1 + } else { + set S [list] + set i 0 + } + set extra "" - if {[llength $argv]>1} { set extra [list -files [lrange $argv 1 end]] } - eval run_tests $suite $::testspec($suite) $extra + if {$i < [llength $argv] && [string range [lindex $argv $i] 0 0]!="-" } { + set files [list] + for {} {$i < [llength $argv]} {incr i} { + set pattern [string map {% *} [lindex $argv $i]] + if {[string range $pattern 0 0]=="-"} break + foreach f $::alltests { + set tail [file tail $f] + if {[lsearch $files $f]<0 && [string match $pattern $tail]} { + lappend files $f + } + } + } + set extra [list -files $files] + } + + eval run_tests $suite $S $extra } } main $argv diff --git a/test/pg_common.tcl b/test/pg_common.tcl new file mode 100644 index 0000000000..ad545ad0aa --- /dev/null +++ b/test/pg_common.tcl @@ -0,0 +1,146 @@ +# 2018 May 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +package require sqlite3 +package require Pgtcl + +set db [pg_connect -conninfo "dbname=postgres user=postgres password=postgres"] +sqlite3 sqlite "" + +proc execsql {sql} { + + set lSql [list] + set frag "" + while {[string length $sql]>0} { + set i [string first ";" $sql] + if {$i>=0} { + append frag [string range $sql 0 $i] + set sql [string range $sql $i+1 end] + if {[sqlite complete $frag]} { + lappend lSql $frag + set frag "" + } + } else { + set frag $sql + set sql "" + } + } + if {$frag != ""} { + lappend lSql $frag + } + #puts $lSql + + set ret "" + foreach stmt $lSql { + set res [pg_exec $::db $stmt] + set err [pg_result $res -error] + if {$err!=""} { error $err } + for {set i 0} {$i < [pg_result $res -numTuples]} {incr i} { + if {$i==0} { + set ret [pg_result $res -getTuple 0] + } else { + append ret " [pg_result $res -getTuple $i]" + } + # lappend ret {*}[pg_result $res -getTuple $i] + } + pg_result $res -clear + } + + set ret +} + +proc execsql_test {tn sql} { + set res [execsql $sql] + set sql [string map {string_agg group_concat} $sql] + puts $::fd "do_execsql_test $tn {" + puts $::fd " [string trim $sql]" + puts $::fd "} {$res}" + puts $::fd "" +} + +# Same as [execsql_test], except coerce all results to floating point values +# with two decimal points. +# +proc execsql_float_test {tn sql} { + set F "%.4f" + set T 0.0001 + set res [execsql $sql] + set res2 [list] + foreach r $res { + if {$r != ""} { set r [format $F $r] } + lappend res2 $r + } + + set sql [string trim $sql] +puts $::fd [subst -nocommands { +do_test $tn { + set myres {} + foreach r [db eval {$sql}] { + lappend myres [format $F [set r]] + } + set res2 {$res2} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-$T) || [set r]>([set r2]+$T)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} +}] +} + +proc start_test {name date} { + set dir [file dirname $::argv0] + set output [file join $dir $name.test] + set ::fd [open $output w] +puts $::fd [string trimleft " +# $date +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +#################################################### +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! +#################################################### +"] + puts $::fd {set testdir [file dirname $argv0]} + puts $::fd {source $testdir/tester.tcl} + puts $::fd "set testprefix $name" + puts $::fd "" +} + +proc -- {args} { + puts $::fd "# $args" +} + +proc ========== {args} { + puts $::fd "#[string repeat = 74]" + puts $::fd "" +} + +proc finish_test {} { + puts $::fd finish_test + close $::fd +} + +proc ifcapable {arg} { + puts $::fd "ifcapable $arg { finish_test ; return }" +} + diff --git a/test/pragma.test b/test/pragma.test index 27400917d8..90cd7e2dfe 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -1932,6 +1932,29 @@ do_test 23.5 { PRAGMA foreign_key_list(t2); } } {0 0 t1 y {} {NO ACTION} {NO ACTION} NONE} +db2 close +ifcapable !has_codec { + reset_db + do_execsql_test 24.0 { + PRAGMA page_size = 1024; + CREATE TABLE t1(a, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES('a', 'b', 'c'); + PRAGMA integrity_check; + } {ok} + + set r [db one {SELECT rootpage FROM sqlite_master WHERE name = 't1'}] + db close + hexio_write test.db [expr $r*1024 - 16] 000000000000000701040f0f1f616263 + + sqlite3 db test.db + do_catchsql_test 24.1 { + SELECT * FROM t1; + } {1 {database disk image is malformed}} + do_catchsql_test 24.2 { + PRAGMA integrity_check; + } {0 {{database disk image is malformed}}} +} database_never_corrupt finish_test diff --git a/test/pragma4.test b/test/pragma4.test index 9a89b247de..d3ded75443 100644 --- a/test/pragma4.test +++ b/test/pragma4.test @@ -80,5 +80,24 @@ foreach {tn sql} { do_pragma_ncol_test 1.$tn.1 $sql 0 } +# EXPLAIN on a PRAGMA integrity_check. +# Verify that that P4_INTARRAY argument to OP_IntegrityCk is rendered +# correctly. +# +db close +forcedelete test.db +sqlite3 db test.db +do_test pragma4-2.100 { + db eval { + PRAGMA page_size=512; + CREATE TABLE t1(x); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10000) + INSERT INTO t1(x) SELECT zeroblob(300) FROM c; + CREATE TABLE t2(y); + DROP TABLE t1; + } + string map {\[ x \] x \173 {} \175 {}} \ + [db eval {EXPLAIN PRAGMA integrity_check}] +} {/ IntegrityCk 2 2 1 x[0-9]+,1x /} finish_test diff --git a/test/pragma5.test b/test/pragma5.test new file mode 100644 index 0000000000..d2c58000cf --- /dev/null +++ b/test/pragma5.test @@ -0,0 +1,64 @@ +# 2017 August 25 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests for the PRAGMA command. Specifically, +# those pragmas enabled at build time by setting: +# +# -DSQLITE_INTROSPECTION_PRAGMAS +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix pragma5 + +if { [catch {db one "SELECT count(*) FROM pragma_function_list"}] } { + finish_test + return +} + +db function external external + +do_execsql_test 1.0 { + PRAGMA table_info(pragma_function_list) +} { + 0 name {} 0 {} 0 + 1 builtin {} 0 {} 0 +} +do_execsql_test 1.1 { + SELECT * FROM pragma_function_list WHERE name='upper' AND builtin +} {upper 1} +do_execsql_test 1.2 { + SELECT * FROM pragma_function_list WHERE name LIKE 'exter%'; +} {external 0} + +ifcapable fts5 { + do_execsql_test 2.0 { + PRAGMA table_info(pragma_module_list) + } { + 0 name {} 0 {} 0 + } + do_execsql_test 2.1 { + SELECT * FROM pragma_module_list WHERE name='fts5' + } {fts5} +} + +do_execsql_test 3.0 { + PRAGMA table_info(pragma_pragma_list) +} { + 0 name {} 0 {} 0 +} +do_execsql_test 3.1 { + SELECT * FROM pragma_pragma_list WHERE name='pragma_list' +} {pragma_list} + + +finish_test diff --git a/test/printf.test b/test/printf.test index 6103d8acf8..d768898fb9 100644 --- a/test/printf.test +++ b/test/printf.test @@ -3757,25 +3757,23 @@ do_test printf-15.3 { # Now test malloc() failure within a sqlite3_mprintf(): # -ifcapable memdebug { - foreach var {a b c d} { - set $var [string repeat $var 400] - } - set str1 "[string repeat A 360]%d%d%s" - set str2 [string repeat B 5000] - set zSuccess "[string repeat A 360]11[string repeat B 5000]" - foreach ::iRepeat {0 1} { - set nTestNum 1 - while {1} { - sqlite3_memdebug_fail $nTestNum -repeat $::iRepeat - set z [sqlite3_mprintf_str $str1 1 1 $str2] - set nFail [sqlite3_memdebug_fail -1 -benign nBenign] - do_test printf-malloc-$::iRepeat.$nTestNum { - expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)} - } {1} - if {$nFail == 0} break - incr nTestNum - } +foreach var {a b c d} { + set $var [string repeat $var 400] +} +set str1 "[string repeat A 360]%d%d%s" +set str2 [string repeat B 5000] +set zSuccess "[string repeat A 360]11[string repeat B 5000]" +foreach ::iRepeat {0 1} { + set nTestNum 1 + while {1} { + sqlite3_memdebug_fail $nTestNum -repeat $::iRepeat + set z [sqlite3_mprintf_str $str1 1 1 $str2] + set nFail [sqlite3_memdebug_fail -1 -benign nBenign] + do_test printf-malloc-$::iRepeat.$nTestNum { + expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)} + } {1} + if {$nFail == 0} break + incr nTestNum } } diff --git a/test/printf2.test b/test/printf2.test index d30966d167..998038f88e 100644 --- a/test/printf2.test +++ b/test/printf2.test @@ -148,6 +148,63 @@ do_execsql_test printf2-4.10 { SELECT printf('|%,d|%,d|',1234567890,-1234567890); } {|1,234,567,890|-1,234,567,890|} +# 2018-02-19. Unicode characters with %c +do_execsql_test printf2-5.100 { + SELECT printf('(%8c)',char(11106)); +} {{( ⭢)}} +do_execsql_test printf2-5.101 { + SELECT printf('(%-8c)',char(11106)); +} {{(⭢ )}} +do_execsql_test printf2-5.102 { + SELECT printf('(%5.3c)',char(1492)); +} {{( ההה)}} +do_execsql_test printf2-5.103 { + SELECT printf('(%-5.3c)',char(1492)); +} {{(ההה )}} +do_execsql_test printf2-5.104 { + SELECT printf('(%3.3c)',char(1492)); +} {{(ההה)}} +do_execsql_test printf2-5.105 { + SELECT printf('(%-3.3c)',char(1492)); +} {{(ההה)}} +do_execsql_test printf2-5.104 { + SELECT printf('(%2c)',char(1513)); +} {{( ש)}} +do_execsql_test printf2-5.106 { + SELECT printf('(%-2c)',char(1513)); +} {{(ש )}} + +# 2018-02-19. Unicode characters with the "!" flag in %s and friends. +do_execsql_test printf2-6.100 { + SELECT printf('(%!.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {(הנה)} +do_execsql_test printf2-6.101 { + SELECT printf('(%.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {(הנה)} +do_execsql_test printf2-6.102 { + SELECT printf('(%!5.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {{( הנה)}} +do_execsql_test printf2-6.103 { + SELECT printf('(%8.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {{( הנה)}} +do_execsql_test printf2-6.104 { + SELECT printf('(%!-5.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {{(הנה )}} +do_execsql_test printf2-6.105 { + SELECT printf('(%-8.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {{(הנה )}} +do_execsql_test printf2-6.106 { + SELECT printf('(%!.3Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {('הנה')} +do_execsql_test printf2-6.107 { + SELECT printf('(%.6Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {('הנה')} +do_execsql_test printf2-6.108 { + SELECT printf('(%!7.3Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {{( 'הנה')}} +do_execsql_test printf2-6.109 { + SELECT printf('(%10.6Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד'); +} {{( 'הנה')}} finish_test diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 614ce35458..3d51b7a812 100755 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -79,6 +79,7 @@ array set ::Configs [strip_comments { -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_THREADSAFE -DSQLITE_TCL_DEFAULT_FULLMUTEX=1 + -DSQLITE_USER_AUTHENTICATION=1 } "Secure-Delete" { -O2 @@ -114,7 +115,7 @@ array set ::Configs [strip_comments { } "Debug-One" { --disable-shared - -O2 + -O2 -funsigned-char -DSQLITE_DEBUG=1 -DSQLITE_MEMDEBUG=1 -DSQLITE_MUTEX_NOOP=1 @@ -126,6 +127,8 @@ array set ::Configs [strip_comments { -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_HIDDEN_COLUMNS -DSQLITE_MAX_ATTACHED=125 + -DSQLITE_MUTATION_TEST + --enable-fts5 --enable-json1 } "Fast-One" { -O6 @@ -172,6 +175,7 @@ array set ::Configs [strip_comments { -DSQLITE_OMIT_TRACE=1 -DSQLITE_TEMP_STORE=3 -DSQLITE_THREADSAFE=2 + -DSQLITE_ENABLE_DESERIALIZE=1 --enable-json1 --enable-fts5 --enable-session } "Locking-Style" { @@ -265,7 +269,7 @@ array set ::Configs [strip_comments { array set ::Platforms [strip_comments { Linux-x86_64 { "Check-Symbols" checksymbols - "Fast-One" fuzztest + "Fast-One" "fuzztest test" "Debug-One" "mptest test" "Have-Not" test "Secure-Delete" test @@ -733,6 +737,9 @@ proc makeCommand { targets makeOpts cflags opts } { set nmakeDir [file nativename $::SRCDIR] set nmakeFile [file nativename [file join $nmakeDir Makefile.msc]] lappend result nmake /f $nmakeFile TOP=$nmakeDir + set tclDir [file nativename [file normalize \ + [file dirname [file dirname [info nameofexecutable]]]]] + lappend result "TCLDIR=$tclDir" if {[regexp {USE_STDCALL=1} $cflags]} { lappend result USE_STDCALL=1 } diff --git a/test/resetdb.test b/test/resetdb.test new file mode 100644 index 0000000000..ab52d7dd38 --- /dev/null +++ b/test/resetdb.test @@ -0,0 +1,251 @@ +# 2018-04-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. +# +#*********************************************************************** +# Test cases for SQLITE_DBCONFIG_RESET_DATABASE +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix resetdb + +do_not_use_codec + +ifcapable !vtab||!compound { + finish_test + return +} + +# In the "inmemory_journal" permutation, each new connection executes +# "PRAGMA journal_mode = memory". This fails with SQLITE_BUSY if attempted +# on a wal mode database with existing connections. For this and a few +# other reasons, this test is not run as part of "inmemory_journal". +# +# Permutation "journaltest" does not support wal mode. +# +if {[permutation]=="inmemory_journal" + || [permutation]=="journaltest" +} { + finish_test + return +} + +# Create a sample database +do_execsql_test 100 { + PRAGMA auto_vacuum = 0; + PRAGMA page_size=4096; + CREATE TABLE t1(a,b); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20) + INSERT INTO t1(a,b) SELECT x, randomblob(300) FROM c; + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1b ON t1(b); + SELECT sum(a), sum(length(b)) FROM t1; + PRAGMA integrity_check; + PRAGMA journal_mode; + PRAGMA page_count; +} {210 6000 ok delete 8} + +# Verify that the same content is seen from a separate database connection +sqlite3 db2 test.db +do_test 110 { + execsql { + SELECT sum(a), sum(length(b)) FROM t1; + PRAGMA integrity_check; + PRAGMA journal_mode; + PRAGMA page_count; + } db2 +} {210 6000 ok delete 8} + +do_test 200 { + # Thoroughly corrupt the database file by overwriting the first + # page with randomness. + catchsql { + UPDATE sqlite_dbpage SET data=randomblob(4096) WHERE pgno=1; + PRAGMA quick_check; + } +} {1 {unsupported file format}} +do_test 201 { + catchsql { + PRAGMA quick_check; + } db2 +} {1 {unsupported file format}} + +do_test 210 { + # Reset the database file using SQLITE_DBCONFIG_RESET_DATABASE + sqlite3_db_config db RESET_DB 1 + db eval VACUUM + sqlite3_db_config db RESET_DB 0 + + # Verify that the reset took, even on the separate database connection + catchsql { + PRAGMA page_count; + PRAGMA page_size; + PRAGMA quick_check; + PRAGMA journal_mode; + } db2 +} {0 {1 4096 ok delete}} + +# Delete the old connections and database and start over again +# with a different page size and in WAL mode. +# +db close +db2 close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 300 { + PRAGMA auto_vacuum = 0; + PRAGMA page_size=8192; + PRAGMA journal_mode=WAL; + CREATE TABLE t1(a,b); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20) + INSERT INTO t1(a,b) SELECT x, randomblob(1300) FROM c; + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1b ON t1(b); + SELECT sum(a), sum(length(b)) FROM t1; + PRAGMA integrity_check; + PRAGMA journal_mode; + PRAGMA page_size; + PRAGMA page_count; +} {wal 210 26000 ok wal 8192 12} +sqlite3 db2 test.db +do_test 310 { + execsql { + SELECT sum(a), sum(length(b)) FROM t1; + PRAGMA integrity_check; + PRAGMA journal_mode; + PRAGMA page_size; + PRAGMA page_count; + } db2 +} {210 26000 ok wal 8192 12} + +# Corrupt the database again +do_catchsql_test 320 { + UPDATE sqlite_dbpage SET data=randomblob(8192) WHERE pgno=1; + PRAGMA quick_check +} {1 {file is not a database}} + +do_test 330 { + catchsql { + PRAGMA quick_check + } db2 +} {1 {file is not a database}} + +db2 cache flush ;# Required by permutation "prepare". + +# Reset the database yet again. Verify that the page size and +# journal mode are preserved. +# +do_test 400 { + sqlite3_db_config db RESET_DB 1 + db eval VACUUM + sqlite3_db_config db RESET_DB 0 + catchsql { + PRAGMA page_count; + PRAGMA page_size; + PRAGMA journal_mode; + PRAGMA quick_check; + } db2 +} {0 {1 8192 wal ok}} +db2 close + +# Reset the database yet again. This time immediately after it is closed +# and reopened. So that the VACUUM is the first statement run. +# +db close +sqlite3 db test.db +do_test 500 { + sqlite3_finalize [ + sqlite3_prepare db "SELECT 1 FROM sqlite_master LIMIT 1" -1 tail + ] + sqlite3_db_config db RESET_DB 1 + db eval VACUUM + sqlite3_db_config db RESET_DB 0 + sqlite3 db2 test.db + catchsql { + PRAGMA page_count; + PRAGMA page_size; + PRAGMA journal_mode; + PRAGMA quick_check; + } db2 +} {0 {1 8192 wal ok}} +db2 close + +#------------------------------------------------------------------------- +reset_db +sqlite3 db2 test.db +do_execsql_test 600 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(1), (2), (3), (4); +} {wal} + +do_execsql_test -db db2 610 { + SELECT * FROM t1 +} {1 2 3 4} + +do_test 620 { + set res [list] + db2 eval {SELECT a FROM t1} { + lappend res $a + if {$a==3} { + sqlite3_db_config db RESET_DB 1 + db eval VACUUM + sqlite3_db_config db RESET_DB 0 + } + } + + set res +} {1 2 3 4} + +do_execsql_test -db db2 630 { + SELECT * FROM sqlite_master +} {} + +#------------------------------------------------------------------------- +db2 close +reset_db + +do_execsql_test 700 { + PRAGMA page_size=512; + PRAGMA auto_vacuum = 0; + CREATE TABLE t1(a,b,c); + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1bc ON t1(b,c); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) + INSERT INTO t1(a,b,c) SELECT x, randomblob(100),randomblob(100) FROM c; + PRAGMA page_count; + PRAGMA integrity_check; +} {19 ok} + +if {[nonzero_reserved_bytes]} { + finish_test + return +} + +do_execsql_test 710 { + UPDATE sqlite_dbpage SET data= + X'53514C69746520666F726D61742033000200030100402020000000000000001300000000000000000000000300000004000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000D00000003017C0001D801AC017C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E03061715110145696E6465787431626374310443524541544520494E4445582074316263204F4E20743128622C63292A0206171311013F696E64657874316174310343524541544520494E44455820743161204F4E20743128612926010617111101397461626C657431743102435245415445205441424C4520743128612C622C6329' WHERE pgno=1; +} + +do_execsql_test 720 { + PRAGMA integrity_check; +} {ok} + +do_test 730 { + sqlite3_db_config db RESET_DB 1 + db eval VACUUM + sqlite3_db_config db RESET_DB 0 +} {0} + +do_execsql_test 740 { + PRAGMA page_count; + PRAGMA integrity_check; +} {1 ok} + +finish_test diff --git a/test/rollback.test b/test/rollback.test index 60a6190317..423bf20fce 100644 --- a/test/rollback.test +++ b/test/rollback.test @@ -83,6 +83,7 @@ if {$tcl_platform(platform) == "unix" && [permutation] ne "onefile" && [permutation] ne "inmemory_journal" && [permutation] ne "atomic-batch-write" + && [atomic_batch_write test.db]==0 } { do_test rollback-2.1 { execsql { diff --git a/test/rollback2.test b/test/rollback2.test index 3ba0f3f9fd..70aecc3377 100644 --- a/test/rollback2.test +++ b/test/rollback2.test @@ -101,7 +101,7 @@ do_rollback_test 2.2 -setup { # do_eqp_test 3.1 { SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h DESC; -} {0 0 0 {SCAN TABLE t1 USING INDEX i1}} +} {SCAN TABLE t1 USING INDEX i1} do_rollback_test 3.2 -setup { BEGIN; DELETE FROM t1 WHERE (i%2)==1; @@ -131,7 +131,7 @@ do_execsql_test 4.1 { UPDATE t1 SET h = $leader || h; } do_eqp_test 4.2 { SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h ASC; -} {0 0 0 {SCAN TABLE t1 USING INDEX i1}} +} {SCAN TABLE t1 USING INDEX i1} do_rollback_test 4.3 -setup { BEGIN; DELETE FROM t1 WHERE (i%2)==1; diff --git a/test/rowvalue.test b/test/rowvalue.test index 5f2701c733..b8ba2e0447 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -175,19 +175,19 @@ do_execsql_test 7.0 { foreach {tn sql res eqp} { 1 "SELECT * FROM xy WHERE (i, j) IS (2, 2)" {2 2 2} - "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid=?)}" + "SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid=?)" 2 "SELECT * FROM xy WHERE (k, j) < (2, 3)" {1 1 1 2 2 2} - "0 0 0 {SCAN TABLE xy}" + "SCAN TABLE xy" 3 "SELECT * FROM xy WHERE (i, j) < (2, 3)" {1 1 1 2 2 2} - "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid (2, 1)" {2 2 2 3 3 3 4 4 4} - "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}" + "SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)" 5 "SELECT * FROM xy WHERE (i, j) > ('2', 1)" {2 2 2 3 3 3 4 4 4} - "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}" + "SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)" } { do_eqp_test 7.$tn.1 $sql $eqp @@ -394,4 +394,156 @@ do_execsql_test 16.5 { 3 i ii iii iv } +do_execsql_test 17.0 { + CREATE TABLE b1(a, b); + CREATE TABLE b2(x); +} + +do_execsql_test 17.1 { + SELECT * FROM b2 CROSS JOIN b1 + WHERE b2.x=b1.a AND (b1.a, 2) + IN (VALUES(1, 2)); +} {} + +do_execsql_test 18.0 { + CREATE TABLE b3 ( a, b, PRIMARY KEY (a, b) ); + CREATE TABLE b4 ( a ); + CREATE TABLE b5 ( a, b ); + INSERT INTO b3 VALUES (1, 1), (1, 2); + INSERT INTO b4 VALUES (1); + INSERT INTO b5 VALUES (1, 1), (1, 2); +} + +do_execsql_test 18.1 { + SELECT * FROM b3 WHERE (SELECT b3.a, b3.b) IN ( SELECT a, b FROM b5 ) +} {1 1 1 2} +do_execsql_test 18.2 { + SELECT * FROM b3 WHERE (VALUES(b3.a, b3.b)) IN ( SELECT a, b FROM b5 ); +} {1 1 1 2} +do_execsql_test 18.3 { + SELECT * FROM b3 WHERE (b3.a, b3.b) IN ( SELECT a, b FROM b5 ); +} {1 1 1 2} +do_execsql_test 18.4 { + SELECT * FROM b3 JOIN b4 ON b4.a = b3.a + WHERE (SELECT b3.a, b3.b) IN ( SELECT a, b FROM b5 ); +} {1 1 1 1 2 1} +do_execsql_test 18.5 { + SELECT * FROM b3 JOIN b4 ON b4.a = b3.a + WHERE (VALUES(b3.a, b3.b)) IN ( SELECT a, b FROM b5 ); +} {1 1 1 1 2 1} +do_execsql_test 18.6 { + SELECT * FROM b3 JOIN b4 ON b4.a = b3.a + WHERE (b3.a, b3.b) IN ( SELECT a, b FROM b5 ); +} {1 1 1 1 2 1} + + +# 2018-02-13 Ticket https://www.sqlite.org/src/tktview/f484b65f3d6230593c3 +# Incorrect result from a row-value comparison in the WHERE clause. +# +do_execsql_test 19.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY,b); + INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3,33),(4,44); + SELECT * FROM t1 WHERE (a,b)>(0,0) ORDER BY a; +} {1 11 2 22 3 33 4 44} +do_execsql_test 19.2 { + SELECT * FROM t1 WHERE (a,b)>=(0,0) ORDER BY a; +} {1 11 2 22 3 33 4 44} +do_execsql_test 19.3 { + SELECT * FROM t1 WHERE (a,b)<(5,0) ORDER BY a DESC; +} {4 44 3 33 2 22 1 11} +do_execsql_test 19.4 { + SELECT * FROM t1 WHERE (a,b)<=(5,0) ORDER BY a DESC; +} {4 44 3 33 2 22 1 11} +do_execsql_test 19.5 { + SELECT * FROM t1 WHERE (a,b)>(3,0) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.6 { + SELECT * FROM t1 WHERE (a,b)>=(3,0) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.7 { + SELECT * FROM t1 WHERE (a,b)<(3,0) ORDER BY a DESC; +} {2 22 1 11} +do_execsql_test 19.8 { + SELECT * FROM t1 WHERE (a,b)<=(3,0) ORDER BY a DESC; +} {2 22 1 11} +do_execsql_test 19.9 { + SELECT * FROM t1 WHERE (a,b)>(3,32) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.10 { + SELECT * FROM t1 WHERE (a,b)>(3,33) ORDER BY a; +} {4 44} +do_execsql_test 19.11 { + SELECT * FROM t1 WHERE (a,b)>=(3,33) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.12 { + SELECT * FROM t1 WHERE (a,b)>=(3,34) ORDER BY a; +} {4 44} +do_execsql_test 19.13 { + SELECT * FROM t1 WHERE (a,b)<(3,34) ORDER BY a DESC; +} {3 33 2 22 1 11} +do_execsql_test 19.14 { + SELECT * FROM t1 WHERE (a,b)<(3,33) ORDER BY a DESC; +} {2 22 1 11} +do_execsql_test 19.15 { + SELECT * FROM t1 WHERE (a,b)<=(3,33) ORDER BY a DESC; +} {3 33 2 22 1 11} +do_execsql_test 19.16 { + SELECT * FROM t1 WHERE (a,b)<=(3,32) ORDER BY a DESC; +} {2 22 1 11} +do_execsql_test 19.21 { + SELECT * FROM t1 WHERE (0,0)<(a,b) ORDER BY a; +} {1 11 2 22 3 33 4 44} +do_execsql_test 19.22 { + SELECT * FROM t1 WHERE (0,0)<=(a,b) ORDER BY a; +} {1 11 2 22 3 33 4 44} +do_execsql_test 19.23 { + SELECT * FROM t1 WHERE (5,0)>(a,b) ORDER BY a DESC; +} {4 44 3 33 2 22 1 11} +do_execsql_test 19.24 { + SELECT * FROM t1 WHERE (5,0)>=(a,b) ORDER BY a DESC; +} {4 44 3 33 2 22 1 11} +do_execsql_test 19.25 { + SELECT * FROM t1 WHERE (3,0)<(a,b) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.26 { + SELECT * FROM t1 WHERE (3,0)<=(a,b) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.27 { + SELECT * FROM t1 WHERE (3,0)>(a,b) ORDER BY a DESC; +} {2 22 1 11} +do_execsql_test 19.28 { + SELECT * FROM t1 WHERE (3,0)>=(a,b) ORDER BY a DESC; +} {2 22 1 11} +do_execsql_test 19.29 { + SELECT * FROM t1 WHERE (3,32)<(a,b) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.30 { + SELECT * FROM t1 WHERE (3,33)<(a,b) ORDER BY a; +} {4 44} +do_execsql_test 19.31 { + SELECT * FROM t1 WHERE (3,33)<=(a,b) ORDER BY a; +} {3 33 4 44} +do_execsql_test 19.32 { + SELECT * FROM t1 WHERE (3,34)<=(a,b) ORDER BY a; +} {4 44} +do_execsql_test 19.33 { + SELECT * FROM t1 WHERE (3,34)>(a,b) ORDER BY a DESC; +} {3 33 2 22 1 11} +do_execsql_test 19.34 { + SELECT * FROM t1 WHERE (3,33)>(a,b) ORDER BY a DESC; +} {2 22 1 11} +do_execsql_test 19.35 { + SELECT * FROM t1 WHERE (3,33)>=(a,b) ORDER BY a DESC; +} {3 33 2 22 1 11} +do_execsql_test 19.36 { + SELECT * FROM t1 WHERE (3,32)>=(a,b) ORDER BY a DESC; +} {2 22 1 11} + +# 2018-02-18: Memory leak nexted row-value. Detected by OSSFuzz. +# +do_catchsql_test 20.1 { + SELECT 1 WHERE (2,(2,0)) IS (2,(2,0)); +} {0 1} + finish_test diff --git a/test/rowvalue4.test b/test/rowvalue4.test index 2e6a28c230..5c0d170f59 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -184,34 +184,33 @@ ifcapable stat4 { ANALYZE; } - do_eqp_test 3.1.1 { SELECT * FROM c1 WHERE a=1 AND c=2 } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)} - } - do_eqp_test 3.1.2 { SELECT * FROM c1 WHERE a=1 AND b>'d' AND c=2 } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)} - } - do_eqp_test 3.1.3 { SELECT * FROM c1 WHERE a=1 AND b>'l' AND c=2 } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=? AND b>?)} - } + do_eqp_test 3.1.1 { SELECT * FROM c1 WHERE a=1 AND c=2 } \ + {SEARCH TABLE c1 USING INDEX c1cd (c=?)} + + do_eqp_test 3.1.2 { SELECT * FROM c1 WHERE a=1 AND b>'d' AND c=2 } \ + {SEARCH TABLE c1 USING INDEX c1cd (c=?)} + + do_eqp_test 3.1.3 { SELECT * FROM c1 WHERE a=1 AND b>'l' AND c=2 } \ + {SEARCH TABLE c1 USING INDEX c1ab (a=? AND b>?)} + + do_eqp_test 3.2.1 { SELECT * FROM c1 WHERE a=1 AND c>1 } \ + {SEARCH TABLE c1 USING INDEX c1cd (c>?)} + + do_eqp_test 3.2.2 { SELECT * FROM c1 WHERE a=1 AND c>0 } \ + {SEARCH TABLE c1 USING INDEX c1ab (a=?)} + + do_eqp_test 3.2.3 { SELECT * FROM c1 WHERE a=1 AND c>=1 } \ + {SEARCH TABLE c1 USING INDEX c1ab (a=?)} + + do_eqp_test 3.2.4 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'c') } \ + {SEARCH TABLE c1 USING INDEX c1ab (a=?)} + + do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } \ + {SEARCH TABLE c1 USING INDEX c1cd ((c,d)>(?,?))} + + do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } \ + {SEARCH TABLE c1 USING INDEX c1ab (a=?)} - do_eqp_test 3.2.1 { SELECT * FROM c1 WHERE a=1 AND c>1 } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c>?)} - } - do_eqp_test 3.2.2 { SELECT * FROM c1 WHERE a=1 AND c>0 } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} - } - do_eqp_test 3.2.3 { SELECT * FROM c1 WHERE a=1 AND c>=1 } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} - } - do_eqp_test 3.2.4 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'c') } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} - } - do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd ((c,d)>(?,?))} - } - do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} - } } #------------------------------------------------------------------------ @@ -225,7 +224,7 @@ do_execsql_test 5.0 { WITH i(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM i WHERE i<1000 ) - INSERT INTO d2 SELECT i/3, i%3, i/3 FROM i; + INSERT INTO d2 SELECT i/100, i%100, i/100 FROM i; ANALYZE; } @@ -234,11 +233,12 @@ do_eqp_test 5.1 { (a, b) IN (SELECT x, y FROM d1) AND (c) IN (SELECT y FROM d1) } { - 0 0 0 {SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)} - 0 0 0 {EXECUTE LIST SUBQUERY 1} - 1 0 0 {SCAN TABLE d1} - 0 0 0 {EXECUTE LIST SUBQUERY 2} - 2 0 0 {SCAN TABLE d1} + QUERY PLAN + |--SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?) + |--LIST SUBQUERY + | `--SCAN TABLE d1 + `--LIST SUBQUERY + `--SCAN TABLE d1 } do_execsql_test 6.0 { @@ -249,31 +249,23 @@ do_execsql_test 6.0 { do_eqp_test 6.1 { SELECT * FROM e1 WHERE (a, b) > (?, ?) -} { - 0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)>(?,?))} -} +} {SEARCH TABLE e1 USING INDEX e1ab ((a,b)>(?,?))} + do_eqp_test 6.2 { SELECT * FROM e1 WHERE (a, b) < (?, ?) -} { - 0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)<(?,?))} -} +} {SEARCH TABLE e1 USING INDEX e1ab ((a,b)<(?,?))} + do_eqp_test 6.3 { SELECT * FROM e1 WHERE c = ? AND (d, e) > (?, ?) -} { - 0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?))} -} +} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?))} + do_eqp_test 6.4 { SELECT * FROM e1 WHERE c = ? AND (d, e) < (?, ?) -} { - 0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)<(?,?))} -} +} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)<(?,?))} do_eqp_test 6.5 { SELECT * FROM e1 WHERE (d, e) BETWEEN (?, ?) AND (?, ?) AND c = ? -} { - 0 0 0 - {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))} -} +} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))} #------------------------------------------------------------------------- diff --git a/test/scanstatus.test b/test/scanstatus.test index ed24d97437..778a0c911e 100644 --- a/test/scanstatus.test +++ b/test/scanstatus.test @@ -30,7 +30,7 @@ do_execsql_test 1.0 { } proc do_scanstatus_test {tn res} { - set stmt [db_last_stmt_ptr db] + set stmt [db version -last-stmt-ptr] set idx 0 set ret [list] while {1} { @@ -79,7 +79,7 @@ do_scanstatus_test 1.9 { } do_test 1.9 { - sqlite3_stmt_scanstatus_reset [db_last_stmt_ptr db] + sqlite3_stmt_scanstatus_reset [db version -last-stmt-ptr] } {} do_scanstatus_test 1.10 { @@ -328,7 +328,7 @@ do_scanstatus_test 5.2.2 { do_eqp_test 5.3.1 { SELECT count(*) FROM t2 WHERE y = 'j'; -} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}} +} {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)} do_execsql_test 5.3.2 { SELECT count(*) FROM t2 WHERE y = 'j'; } {19} @@ -340,8 +340,9 @@ do_scanstatus_test 5.3.3 { do_eqp_test 5.4.1 { SELECT count(*) FROM t1, t2 WHERE y = c; } { - 0 0 0 {SCAN TABLE t1 USING COVERING INDEX t1bc} - 0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)} + QUERY PLAN + |--SCAN TABLE t1 USING COVERING INDEX t1bc + `--SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?) } do_execsql_test 5.4.2 { SELECT count(*) FROM t1, t2 WHERE y = c; @@ -356,8 +357,9 @@ do_scanstatus_test 5.4.3 { do_eqp_test 5.5.1 { SELECT count(*) FROM t1, t3 WHERE y = c; } { - 0 0 1 {SCAN TABLE t3} - 0 1 0 {SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?)} + QUERY PLAN + |--SCAN TABLE t3 + `--SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?) } do_execsql_test 5.5.2 { SELECT count(*) FROM t1, t3 WHERE y = c; diff --git a/test/schema6.test b/test/schema6.test index 7de04d51c2..0eb8a1c434 100644 --- a/test/schema6.test +++ b/test/schema6.test @@ -18,6 +18,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix schema6 +do_not_use_codec # Command: check_same_database_content TESTNAME SQL1 SQL2 SQL3 ... # diff --git a/test/schemafault.test b/test/schemafault.test new file mode 100644 index 0000000000..a04c78a0b4 --- /dev/null +++ b/test/schemafault.test @@ -0,0 +1,31 @@ +# 2018-08-19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# Test OOM injection in schema-related operations. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set testprefix schemafault + +do_execsql_test 1.0 { + CREATE TABLE t2(aaa INTTT); + CREATE VIEW v2(xxx , yyy) AS SELECT aaa, aaa+1 FROM t2; +} + +do_faultsim_test 1 -faults oom-* -prep { +} -body { + execsql { SELECT * FROM v2 } +} -test { + faultsim_test_result {0 {}} +} + +finish_test diff --git a/test/securedel.test b/test/securedel.test index a78f466031..8323a30497 100644 --- a/test/securedel.test +++ b/test/securedel.test @@ -17,8 +17,12 @@ source $testdir/tester.tcl unset -nocomplain DEFAULT_SECDEL set DEFAULT_SECDEL 0 -ifcapable secure_delete { - set DEFAULT_SECDEL 1 +ifcapable fast_secure_delete { + set DEFAULT_SECDEL 2 +} else { + ifcapable secure_delete { + set DEFAULT_SECDEL 1 + } } diff --git a/test/select1.test b/test/select1.test index 4d6c07f2d0..7023a6e65d 100644 --- a/test/select1.test +++ b/test/select1.test @@ -545,9 +545,9 @@ do_test select1-6.9.7 { set x [execsql2 { SELECT * FROM test1 a, (select 5, 6) LIMIT 1 }] - regsub -all {sq_[0-9a-fA-F_]+} $x {subquery} x + regsub -all {subquery_[0-9a-fA-F_]+} $x {subquery} x set x -} {a.f1 11 a.f2 22 sqlite_subquery.5 5 sqlite_subquery.6 6} +} {a.f1 11 a.f2 22 subquery.5 5 subquery.6 6} do_test select1-6.9.8 { set x [execsql2 { SELECT * FROM test1 a, (select 5 AS x, 6 AS y) AS b LIMIT 1 @@ -688,7 +688,7 @@ do_test select1-7.2 { do_test select1-7.3 { set v [catch {execsql {SELECT f1 FROM test1 as 'hi', test2 as}} msg] lappend v $msg -} {1 {near "as": syntax error}} +} {1 {incomplete input}} do_test select1-7.4 { set v [catch {execsql { SELECT f1 FROM test1 ORDER BY; diff --git a/test/select5.test b/test/select5.test index 3a787fc767..8f451eacbb 100644 --- a/test/select5.test +++ b/test/select5.test @@ -154,7 +154,7 @@ do_test select5-5.5 { execsql { SELECT a, b FROM t2 GROUP BY a; } -} {1 4 6 4} +} {1 2 6 4} # Test rendering of columns for the GROUP BY clause. # diff --git a/test/selectA.test b/test/selectA.test index 78d04be15d..838e5f4323 100644 --- a/test/selectA.test +++ b/test/selectA.test @@ -1336,11 +1336,14 @@ do_eqp_test 4.1.2 { SELECT a, b FROM t4 WHERE f()==f() ORDER BY 1,2 } { - 1 0 0 {SCAN TABLE t5 USING INDEX i2} - 1 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY} - 2 0 0 {SCAN TABLE t4 USING INDEX i1} - 2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY} - 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} + QUERY PLAN + `--MERGE (UNION ALL) + |--LEFT + | |--SCAN TABLE t5 USING INDEX i2 + | `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY + `--RIGHT + |--SCAN TABLE t4 USING INDEX i1 + `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY } do_execsql_test 4.1.3 { diff --git a/test/selectD.test b/test/selectD.test index 89f999eb6d..9c09b2cca6 100644 --- a/test/selectD.test +++ b/test/selectD.test @@ -169,6 +169,6 @@ do_execsql_test selectD-4.1 { WHERE x1.d>5 GROUP BY x1.d) AS x2 ON t41.b=x2.d; -} {/.*SEARCH SUBQUERY 1 AS x2 USING AUTOMATIC.*/} +} {/*SEARCH SUBQUERY * AS x2 USING AUTOMATIC*/} finish_test diff --git a/test/selectG.test b/test/selectG.test index 86d89b121b..fab4c4ed4d 100644 --- a/test/selectG.test +++ b/test/selectG.test @@ -36,4 +36,24 @@ do_test 100 { } } {100000 5000050000 50000.5 1} +# 2018-01-14. A 100K-entry VALUES clause within a scalar expression does +# not cause processor stack overflow. +# +do_test 110 { + set sql "SELECT (VALUES" + for {set i 1} {$i<100000} {incr i} { + append sql "($i)," + } + append sql "($i));" + db eval $sql +} {1} + +# Only the left-most term of a multi-valued VALUES within a scalar +# expression is evaluated. +# +do_test 120 { + set n [llength [split [db eval "explain $sql"] \n]] + expr {$n<10} +} {1} + finish_test diff --git a/test/server1.test b/test/server1.test index 90673ef000..c809217094 100644 --- a/test/server1.test +++ b/test/server1.test @@ -26,6 +26,15 @@ if {[llength [info command client_step]]==0 || [sqlite3 -has-codec]} { return } +# This test does not work on older PPC Macs due to problems in the +# pthreads library. So skip it. +# +if {$tcl_platform(machine)=="Power Macintosh" && + $tcl_platform(byteOrder)=="bigEndian"} { + finish_test + return +} + # The sample server implementation does not work right when memory # management is enabled. # diff --git a/test/sessionfuzz-data1.db b/test/sessionfuzz-data1.db new file mode 100644 index 0000000000..df10e10bcd Binary files /dev/null and b/test/sessionfuzz-data1.db differ diff --git a/test/sessionfuzz.c b/test/sessionfuzz.c new file mode 100644 index 0000000000..7f2de51092 --- /dev/null +++ b/test/sessionfuzz.c @@ -0,0 +1,1018 @@ +/* +** 2018-03-01 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements a program used for fuzz-testing the session +** module. +** +** Usage: +** +** sessionfuzz setup -- Generate starter test cases +** sessionfuzz run FILE ... -- Run a test fuzz on FILE +** sesssiofuzz run SQLAR ... -- Run all test cases in the SQL Archive +** +** Compiling: +** +** (1) Have a version of SQLite that supports SQLITE_ENABLE_MEMDB +** in the local directory. +** (2) Run: +** +** gcc -Wall -O3 -o sessionfuzz sessionfuzz.c -lz +** +** Use with AFL (American Fuzzy Lop - http://lcamtuf.coredump.cx/afl/) +** +** (1) ./afl-gcc -O3 -o sessionfuzz sessionfuzz.c -lz +** (2) mkdir session-init session-run session-cases +** (3) cd session-init; ../sessionfuzz setup; cd .. +** (4) ./afl -i session-init -o session-run -- ./sessionfuzz run @@ +** ... let the previous step run for a while. Weeks, maybe. +** (5) ./afl-cmin -i session-run -o session-cases +** +** The afl-cmin command on step (5) writes a minimal set of test cases +** for coverage into the session-cases directory. Gather the cases written +** there into an SQL Archive using a command like this: +** +** sqlite3 session-cases.db -Ac session-cases +** +** Then repeat the test using: +** +** ./sessionfuzz run session-cases.db +*/ + +/* +** We will import the entire SQLite source file to make compiling easier +*/ +#ifdef SQLITE_DEBUG +#undef SQLITE_DEBUG +#endif + +#ifdef SQLITE_THREADSAFE +#undef SQLITE_THREADSAFE +#endif + +#define SQLITE_DEBUG 1 +#define SQLITE_THREADSAFE 0 +#define SQLITE_OMIT_LOAD_EXTENSION 0 +#define SQLITE_ENABLE_SESSION 1 +#define SQLITE_ENABLE_PREUPDATE_HOOK 1 +#define SQLITE_ENABLE_DESERIALIZE 1 +#include "sqlite3.c" + +/* Create a test database. This will be an in-memory database */ +static const char zInitSql[] = + "CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d);\n" + "CREATE TABLE t2(e TEXT PRIMARY KEY NOT NULL,f,g);\n" + "CREATE TABLE t3(w REAL PRIMARY KEY NOT NULL,x,y);\n" + "CREATE TABLE t4(z PRIMARY KEY) WITHOUT ROWID;\n" +; + +/* Code to populate the database */ +static const char zFillSql[] = + "INSERT INTO t1(a,b,c,d) VALUES\n" + " (1,2,3,4),\n" + " (2,3.5,'four',x'556677'),\n" + " (3,null,'xyz',15),\n" + " (4,'bubba',0x80000000,0.0);\n" + "INSERT INTO t1 SELECT a+4,c,d,b FROM t1;\n" + "INSERT INTO t1 SELECT a+8,d,b,c FROM t1;\n" + "INSERT INTO t1 SELECT a+16,d,c,b FROM t1;\n" + "INSERT INTO t1 SELECT a+32,b,d,c FROM t1;\n" + "INSERT INTO t2 SELECT printf('x%dy',a),b,c FROM t1;\n" + "INSERT INTO t3 SELECT a*1.1,b,c FROM t1;\n" + "INSERT INTO t4 SELECT a||','||quote(b) FROM t1;\n" +; + +/* A database file created by running the two scripts above */ +static const unsigned char aDbBytes[] = { + 83, 81, 76,105,116,101, 32,102,111,114,109, 97,116, 32, 51, 0, 2, 0, 1, + 1, 0, 64, 32, 32, 0, 0, 0, 13, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 46, 32,152, 13, 1,186, 0, 6, 0,176, 0, 1,194, 1, 84, 1,150, + 0,238, 1, 48, 0,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 60, 6, 6, 23, 17, 17, 1,101,116, 97, 98,108,101,116, + 52,116, 52, 7, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 52, + 40,122, 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 89, 41, 32, 87, 73, 84, + 72, 79, 85, 84, 32, 82, 79, 87, 73, 68, 64, 4, 6, 23, 17, 17, 1,109,116, + 97, 98,108,101,116, 51,116, 51, 5, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, + 76, 69, 32,116, 51, 40,119, 32, 82, 69, 65, 76, 32, 80, 82, 73, 77, 65, 82, + 89, 32, 75, 69, 89, 32, 78, 79, 84, 32, 78, 85, 76, 76, 44,120, 44,121, 41, + 34, 5, 5, 23, 55, 17, 1,105,110,100,101,120,115,113,108,105,116,101, 95, + 97,117,116,111,105,110,100,101,120, 95,116, 51, 95, 49,116, 51, 6, 64, 2, + 6, 23, 17, 17, 1,109,116, 97, 98,108,101,116, 50,116, 50, 3, 67, 82, 69, + 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 50, 40,101, 32, 84, 69, 88, 84, + 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 89, 32, 78, 79, 84, 32, 78, 85, + 76, 76, 44,102, 44,103, 41, 34, 3, 5, 23, 55, 17, 1,105,110,100,101,120, + 115,113,108,105,116,101, 95, 97,117,116,111,105,110,100,101,120, 95,116, 50, + 95, 49,116, 50, 4, 0, 0, 0, 8, 0, 0, 0, 0, 60, 1, 6, 23, 17, 17, + 1,101,116, 97, 98,108,101,116, 49,116, 49, 2, 67, 82, 69, 65, 84, 69, 32, + 84, 65, 66, 76, 69, 32,116, 49, 40, 97, 32, 73, 78, 84, 69, 71, 69, 82, 32, + 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 89, 44, 98, 44, 99, 44,100, 41, 5, + 0, 0, 0, 2, 1,246, 0, 0, 0, 0, 10, 1,251, 1,246, 1,177, 1,155, + 1,145, 1,119, 1,109, 1, 87, 1, 76, 1, 50, 1, 40, 1, 18, 1, 7, 0, + 237, 0,227, 0,205, 0,195, 0,169, 0,159, 0,137, 0,126, 0,100, 0, 90, + 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 20, 26, 5, 0, 21, 7, 18,102,111, + 117,114, 64, 12, 0, 0, 0, 0, 0, 0, 85,102,119, 8, 25, 5, 0, 1, 1, + 1, 3, 2, 4, 24, 24, 5, 0, 23, 7, 5, 98,117, 98, 98, 97, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 9, 23, 5, 0, 0, 1, 19, 15, + 120,121,122, 20, 22, 5, 0, 7, 18, 21, 64, 12, 0, 0, 0, 0, 0, 0, 85, + 102,119,102,111,117,114, 8, 21, 5, 0, 1, 1, 1, 2, 4, 3, 24, 20, 5, + 0, 7, 5, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 98, + 117, 98, 98, 97, 8, 19, 4, 0, 1, 19, 15,120,121,122, 20, 18, 5, 0, 18, + 21, 7, 85,102,119,102,111,117,114, 64, 12, 0, 0, 0, 0, 0, 0, 8, 17, + 5, 0, 1, 1, 1, 4, 3, 2, 24, 16, 5, 0, 23, 5, 7, 98,117, 98, 98, + 97, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 15, 5, 0, + 0, 19, 1,120,121,122, 15, 20, 14, 5, 0, 7, 21, 18, 64, 12, 0, 0, 0, + 0, 0, 0,102,111,117,114, 85,102,119, 8, 13, 5, 0, 1, 1, 1, 2, 3, + 4, 24, 12, 5, 0, 7, 23, 5, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, + 98, 97, 0, 0,128, 0, 0, 0, 9, 11, 5, 0, 1, 0, 19, 15,120,121,122, + 20, 10, 5, 0, 18, 7, 21, 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0,102, + 111,117,114, 8, 9, 5, 0, 1, 1, 1, 4, 2, 3, 24, 8, 5, 0, 5, 7, + 23, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, + 97, 8, 7, 4, 0, 19, 1,120,121,122, 15, 20, 6, 5, 0, 21, 18, 7,102, + 111,117,114, 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0, 8, 5, 5, 0, 1, + 1, 1, 3, 4, 2, 24, 4, 5, 0, 23, 5, 7, 98,117, 98, 98, 97, 0, 0, + 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 5, 0, 0, 19, 1, + 120,121,122, 15, 20, 2, 5, 0, 7, 21, 18, 64, 12, 0, 0, 0, 0, 0, 0, + 102,111,117,114, 85,102,119, 0, 0, 0, 9, 52, 0, 0, 0, 8, 26, 5, 0, + 0, 0, 2, 1,246, 0, 0, 0, 0, 13, 1,251, 1,246, 1,181, 1,165, 1, + 152, 1,129, 1,118, 1, 97, 1, 87, 1, 64, 1, 52, 1, 30, 1, 17, 0,252, + 0,240, 0,223, 0,209, 0,185, 0,173, 0,152, 0,141, 0,118, 0,106, 0, + 84, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 27, 3, 21, 19,120, + 50, 55,121,120,121,122, 20, 26, 4, 21, 21, 7,120, 50, 54,121,102,111,117, + 114, 64, 12, 0, 0, 0, 0, 0, 0, 10, 25, 4, 21, 1, 1,120, 50, 53,121, + 3, 2, 21, 24, 4, 21, 23, 7,120, 50, 52,121, 98,117, 98, 98, 97, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 23, 4, 21, 0, 1,120, 50, 51,121, 15, 19, 22, + 4, 21, 7, 18,120, 50, 50,121, 64, 12, 0, 0, 0, 0, 0, 0, 85,102,119, + 10, 21, 4, 21, 1, 1,120, 50, 49,121, 2, 4, 22, 20, 4, 21, 7, 5,120, + 50, 48,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 12, 19, + 4, 21, 1, 19,120, 49, 57,121, 15,120,121,122, 15, 18, 4, 21, 18, 21,120, + 49, 56,121, 85,102,119,102,111,117,114, 10, 17, 4, 21, 1, 1,120, 49, 55, + 121, 4, 3, 19, 16, 4, 21, 23, 5,120, 49, 54,121, 98,117, 98, 98, 97, 0, + 0,128, 0, 0, 0, 11, 15, 4, 21, 0, 19,120, 49, 53,121,120,121,122, 20, + 14, 4, 21, 7, 21,120, 49, 52,121, 64, 12, 0, 0, 0, 0, 0, 0,102,111, + 117,114, 10, 13, 4, 21, 1, 1,120, 49, 51,121, 2, 3, 21, 12, 4, 21, 7, + 23,120, 49, 50,121, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 8, + 11, 3, 21, 1,120, 49, 49,121, 15, 19, 10, 4, 21, 18, 7,120, 49, 48,121, + 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0, 9, 9, 4, 19, 1, 1,120, 57, + 121, 4, 2, 21, 8, 4, 19, 5, 7,120, 56,121, 0, 0,128, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, 7, 4, 19, 19, 1,120, 55,121,120,121,122, + 15, 14, 6, 4, 19, 21, 18,120, 54,121,102,111,117,114, 85,102,119, 9, 5, + 4, 19, 1, 1,120, 53,121, 3, 4, 18, 4, 4, 19, 23, 5,120, 52,121, 98, + 117, 98, 98, 97, 0, 0,128, 0, 0, 0, 10, 3, 4, 19, 0, 19,120, 51,121, + 120,121,122, 19, 2, 4, 19, 7, 21,120, 50,121, 64, 12, 0, 0, 0, 0, 0, + 0,102,111,117,114, 9, 0, 0, 0, 12, 53, 0, 0, 0, 11, 27, 2, 0, 0, + 0, 1, 1,243, 0, 0, 0, 0, 15, 1,243, 1,220, 1,211, 1,202, 1,193, + 1,184, 1,175, 1,166, 1,159, 1,150, 1,141, 1,132, 1,123, 1,114, 1, + 105, 1, 96, 1, 87, 1, 78, 1, 69, 1, 61, 1, 52, 1, 43, 1, 34, 1, 25, + 1, 16, 1, 7, 0,254, 0,245, 0,236, 0,227, 0,219, 0,210, 0,201, 0, + 192, 0,183, 0,174, 0,165, 0,156, 0,147, 0,138, 0,129, 0,121, 0,112, + 0,103, 0, 0, 0, 8, 3, 21, 1,120, 53, 49,121, 51, 8, 3, 21, 1,120, + 53, 48,121, 50, 7, 3, 19, 1,120, 52,121, 4, 8, 3, 21, 1,120, 52, 57, + 121, 49, 8, 3, 21, 1,120, 52, 56,121, 48, 8, 3, 21, 1,120, 52, 55,121, + 47, 8, 3, 21, 1,120, 52, 54,121, 46, 8, 3, 21, 1,120, 52, 53,121, 45, + 8, 3, 21, 1,120, 52, 52,121, 44, 8, 3, 21, 1,120, 52, 51,121, 43, 8, + 3, 21, 1,120, 52, 50,121, 42, 8, 3, 21, 1,120, 52, 49,121, 41, 8, 3, + 21, 1,120, 52, 48,121, 40, 7, 3, 19, 1,120, 51,121, 3, 8, 3, 21, 1, + 120, 51, 57,121, 39, 8, 3, 21, 1,120, 51, 56,121, 38, 8, 3, 21, 1,120, + 51, 55,121, 37, 8, 3, 21, 1,120, 51, 54,121, 36, 8, 3, 21, 1,120, 51, + 53,121, 35, 8, 3, 21, 1,120, 51, 52,121, 34, 8, 3, 21, 1,120, 51, 51, + 121, 33, 8, 3, 21, 1,120, 51, 50,121, 32, 8, 3, 21, 1,120, 51, 49,121, + 31, 8, 3, 21, 1,120, 51, 48,121, 30, 7, 3, 19, 1,120, 50,121, 2, 8, + 3, 21, 1,120, 50, 57,121, 29, 8, 3, 21, 1,120, 50, 56,121, 28, 8, 3, + 21, 1,120, 50, 55,121, 27, 8, 3, 21, 1,120, 50, 54,121, 26, 8, 3, 21, + 1,120, 50, 53,121, 25, 8, 3, 21, 1,120, 50, 52,121, 24, 8, 3, 21, 1, + 120, 50, 51,121, 23, 8, 3, 21, 1,120, 50, 50,121, 22, 8, 3, 21, 1,120, + 50, 49,121, 21, 8, 3, 21, 1,120, 50, 48,121, 20, 6, 3, 19, 9,120, 49, + 121, 8, 3, 21, 1,120, 49, 57,121, 19, 8, 3, 21, 1,120, 49, 56,121, 18, + 8, 3, 21, 1,120, 49, 55,121, 17, 8, 3, 21, 1,120, 49, 54,121, 16, 8, + 3, 21, 1,120, 49, 53,121, 15, 8, 3, 21, 1,120, 49, 52,121, 14, 8, 3, + 21, 1,120, 49, 51,121, 13, 8, 3, 21, 1,120, 49, 50,121, 12, 8, 3, 21, + 1,120, 0, 0, 0, 14, 8, 3, 21, 1,120, 53, 49,121, 51, 5, 0, 0, 0, + 2, 1,246, 0, 0, 0, 0, 18, 1,251, 1,246, 1,156, 1,135, 1,117, 1, + 89, 1, 73, 1, 55, 1, 41, 1, 14, 0,254, 0,228, 0,211, 0,186, 0,170, + 0,149, 0,131, 0,110, 0, 94, 0, 69, 0, 54, 13, 23, 4, 7, 0, 1, 64, + 57, 76,204,204,204,204,205, 15, 23, 22, 4, 7, 7, 18, 64, 56, 51, 51, 51, + 51, 51, 52, 64, 12, 0, 0, 0, 0, 0, 0, 85,102,119, 14, 21, 4, 7, 1, + 1, 64, 55, 25,153,153,153,153,154, 2, 4, 19, 20, 4, 1, 7, 5, 22, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 16, 19, 4, 7, 1, 19, + 64, 52,230,102,102,102,102,103, 15,120,121,122, 19, 18, 4, 7, 18, 21, 64, + 51,204,204,204,204,204,205, 85,102,119,102,111,117,114, 14, 17, 4, 7, 1, + 1, 64, 50,179, 51, 51, 51, 51, 52, 4, 3, 23, 16, 4, 7, 23, 5, 64, 49, + 153,153,153,153,153,154, 98,117, 98, 98, 97, 0, 0,128, 0, 0, 0, 15, 15, + 4, 7, 0, 19, 64, 48,128, 0, 0, 0, 0, 0,120,121,122, 24, 14, 4, 7, + 7, 21, 64, 46,204,204,204,204,204,206, 64, 12, 0, 0, 0, 0, 0, 0,102, + 111,117,114, 14, 13, 4, 7, 1, 1, 64, 44,153,153,153,153,153,154, 2, 3, + 25, 12, 4, 7, 7, 23, 64, 42,102,102,102,102,102,103, 0, 0, 0, 0, 0, + 0, 0, 0, 98,117, 98, 98, 97, 12, 11, 3, 7, 1, 64, 40, 51, 51, 51, 51, + 51, 52, 15, 16, 10, 4, 1, 18, 7, 11, 85,102,119, 64, 12, 0, 0, 0, 0, + 0, 0, 14, 9, 4, 7, 1, 1, 64, 35,204,204,204,204,204,205, 4, 2, 26, + 8, 4, 7, 5, 7, 64, 33,153,153,153,153,153,154, 0, 0,128, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 7, 4, 7, 19, 1, 64, 30,204,204,204, + 204,204,206,120,121,122, 15, 19, 6, 4, 7, 21, 18, 64, 26,102,102,102,102, + 102,103,102,111,117,114, 85,102,119, 14, 5, 4, 7, 1, 1, 64, 22, 0, 0, + 0, 0, 0, 0, 3, 4, 23, 4, 4, 7, 23, 5, 64, 17,153,153,153,153,153, + 154, 98,117, 98, 98, 97, 0, 0,128, 0, 0, 0, 15, 3, 4, 7, 0, 19, 64, + 10,102,102,102,102,102,103,120,121,122, 24, 2, 4, 7, 7, 21, 64, 1,153, + 153,153,153,153,154, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 14, 1, + 4, 7, 1, 1, 0, 0, 0, 17, 45, 0, 0, 0, 16, 23, 2, 0, 0, 0, 1, + 1,239, 0, 0, 0, 0, 20, 1,239, 1,205, 1,192, 1,179, 1,166, 1,153, + 1,140, 1,134, 1,121, 1,108, 1, 95, 1, 82, 1, 69, 1, 56, 1, 43, 1, + 30, 1, 17, 1, 11, 0,254, 0,241, 0,228, 0,215, 0,202, 0,189, 0,176, + 0,163, 0,150, 0,144, 0,131, 0,118, 0,105, 0, 92, 0, 79, 0, 12, 3, + 7, 1, 64, 67, 64, 0, 0, 0, 0, 0, 35, 12, 3, 7, 1, 64, 66,179, 51, + 51, 51, 51, 52, 34, 12, 3, 7, 1, 64, 66, 38,102,102,102,102,103, 33, 12, + 3, 7, 1, 64, 65,153,153,153,153,153,154, 32, 12, 3, 7, 1, 64, 65, 12, + 204,204,204,204,205, 31, 5, 3, 1, 1, 33, 30, 12, 3, 7, 1, 64, 63,230, + 102,102,102,102,103, 29, 12, 3, 7, 1, 64, 62,204,204,204,204,204,206, 28, + 12, 3, 7, 1, 64, 61,179, 51, 51, 51, 51, 52, 27, 12, 3, 7, 1, 64, 60, + 153,153,153,153,153,154, 26, 12, 3, 7, 1, 64, 59,128, 0, 0, 0, 0, 1, + 25, 12, 3, 7, 1, 64, 58,102,102,102,102,102,103, 24, 12, 3, 7, 1, 64, + 57, 76,204,204,204,204,205, 23, 12, 3, 7, 1, 64, 56, 51, 51, 51, 51, 51, + 52, 22, 12, 3, 7, 1, 64, 55, 25,153,153,153,153,154, 21, 5, 3, 1, 1, + 22, 20, 12, 3, 7, 1, 64, 52,230,102,102,102,102,103, 19, 12, 3, 7, 1, + 64, 51,204,204,204,204,204,205, 18, 12, 3, 7, 1, 64, 50,179, 51, 51, 51, + 51, 52, 17, 12, 3, 7, 1, 64, 49,153,153,153,153,153,154, 16, 12, 3, 7, + 1, 64, 48,128, 0, 0, 0, 0, 0, 15, 12, 3, 7, 1, 64, 46,204,204,204, + 204,204,206, 14, 12, 3, 7, 1, 64, 44,153,153,153,153,153,154, 13, 12, 3, + 7, 1, 64, 42,102,102,102,102,102,103, 12, 12, 3, 7, 1, 64, 40, 51, 51, + 51, 51, 51, 52, 11, 5, 3, 1, 1, 11, 10, 12, 3, 7, 1, 64, 35,204,204, + 204,204,204,205, 9, 12, 3, 7, 1, 64, 33,153,153,153,153,153,154, 8, 12, + 3, 7, 1, 64, 30,204,204,204,204,204,206, 7, 12, 3, 7, 1, 64, 26,102, + 102,102,102,102,103, 6, 12, 3, 7, 1, 64, 22, 0, 0, 0, 0, 0, 0, 5, + 12, 3, 7, 1, 64, 17,153,153,153,153,153,154, 4, 12, 3, 7, 1, 64, 10, + 102,102,102,102,102,103, 3, 12, 3, 7, 1, 64, 1,153,153, 0, 0, 0, 19, + 12, 3, 7, 1, 64, 67, 64, 0, 0, 0, 0, 0, 35, 2, 0, 0, 0, 1, 1, + 242, 0, 0, 0, 0, 22, 1,242, 1,218, 1,211, 1,202, 1,192, 1,179, 1, + 172, 1,157, 1,149, 1,141, 1,132, 1,125, 1,116, 1,106, 1, 93, 1, 86, + 1, 74, 1, 63, 1, 47, 1, 40, 1, 31, 1, 16, 1, 8, 0,255, 0,248, 0, + 239, 0,229, 0,216, 0,209, 0,197, 0,186, 0,174, 0,158, 0,151, 0,136, + 0,128, 0,119, 0,112, 0,103, 0, 93, 0, 9, 2, 27, 52, 55, 44, 78, 85, + 76, 76, 8, 2, 25, 52, 54, 44, 51, 46, 53, 6, 2, 21, 52, 53, 44, 50, 8, + 2, 25, 52, 52, 44, 48, 46, 48, 7, 2, 23, 52, 51, 44, 49, 53, 14, 2, 37, + 52, 50, 44, 88, 39, 53, 53, 54, 54, 55, 55, 39, 6, 2, 21, 52, 49, 44, 52, + 15, 2, 39, 52, 48, 44, 50, 49, 52, 55, 52, 56, 51, 54, 52, 56, 11, 2, 31, + 52, 44, 39, 98,117, 98, 98, 97, 39, 10, 2, 29, 51, 57, 44, 39,120,121,122, + 39, 11, 2, 31, 51, 56, 44, 39,102,111,117,114, 39, 6, 2, 21, 51, 55, 44, + 51, 12, 2, 33, 51, 54, 44, 39, 98,117, 98, 98, 97, 39, 9, 2, 27, 51, 53, + 44, 78, 85, 76, 76, 8, 2, 25, 51, 52, 44, 51, 46, 53, 6, 2, 21, 51, 51, + 44, 50, 8, 2, 25, 51, 50, 44, 48, 46, 48, 7, 2, 23, 51, 49, 44, 49, 53, + 14, 2, 37, 51, 48, 44, 88, 39, 53, 53, 54, 54, 55, 55, 39, 8, 2, 25, 51, + 44, 78, 85, 76, 76, 6, 2, 21, 50, 57, 44, 52, 15, 2, 39, 50, 56, 44, 50, + 49, 52, 55, 52, 56, 51, 54, 52, 56, 10, 2, 29, 50, 55, 44, 39,120,121,122, + 39, 11, 2, 31, 50, 54, 44, 39,102,111,117,114, 39, 6, 2, 21, 50, 53, 44, + 51, 12, 2, 33, 50, 52, 44, 39, 98,117, 98, 98, 97, 39, 9, 2, 27, 50, 51, + 44, 78, 85, 76, 76, 8, 2, 25, 50, 50, 44, 51, 46, 53, 6, 2, 21, 50, 49, + 44, 50, 8, 2, 25, 50, 48, 44, 48, 46, 48, 7, 2, 23, 50, 44, 51, 46, 53, + 7, 2, 23, 49, 57, 44, 49, 53, 14, 2, 37, 49, 56, 44, 88, 39, 53, 53, 54, + 54, 55, 55, 39, 6, 2, 21, 49, 55, 44, 52, 12, 2, 33, 49, 54, 44, 39, 98, + 117, 98, 98, 97, 39, 9, 2, 27, 49, 53, 44, 78, 85, 76, 76, 8, 2, 25, 49, + 52, 44, 51, 46, 53, 6, 2, 21, 49, 51, 44, 50, 8, 2, 25, 49, 50, 44, 48, + 46, 48, 7, 2, 23, 49, 49, 44, 49, 53, 14, 2, 37, 49, 48, 44, 88, 0, 0, + 0, 21, 9, 2, 27, 52, 55, 44, 78, 85, 76, 76, 13, 0, 0, 0, 26, 0, 68, + 0, 1,246, 1,224, 1,213, 1,187, 1,177, 1,155, 1,145, 1,119, 1,109, + 1, 87, 1, 76, 1, 50, 1, 40, 1, 18, 1, 7, 0,237, 0,227, 0,205, 0, + 195, 0,169, 0,159, 0,137, 0,126, 0,100, 0, 90, 0, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 20, 26, 5, 0, 21, 7, 18,102,111,117,114, 64, 12, 0, 0, + 0, 0, 0, 0, 85,102,119, 8, 25, 5, 0, 1, 1, 1, 3, 2, 4, 24, 24, + 5, 0, 23, 7, 5, 98,117, 98, 98, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128, 0, 0, 0, 9, 23, 5, 0, 0, 1, 19, 15,120,121,122, 20, 22, 5, + 0, 7, 18, 21, 64, 12, 0, 0, 0, 0, 0, 0, 85,102,119,102,111,117,114, + 8, 21, 5, 0, 1, 1, 1, 2, 4, 3, 24, 20, 5, 0, 7, 5, 23, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 98,117, 98, 98, 97, 8, 19, + 4, 0, 1, 19, 15,120,121,122, 20, 18, 5, 0, 18, 21, 7, 85,102,119,102, + 111,117,114, 64, 12, 0, 0, 0, 0, 0, 0, 8, 17, 5, 0, 1, 1, 1, 4, + 3, 2, 24, 16, 5, 0, 23, 5, 7, 98,117, 98, 98, 97, 0, 0,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 15, 5, 0, 0, 19, 1,120,121,122, + 15, 20, 14, 5, 0, 7, 21, 18, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117, + 114, 85,102,119, 8, 13, 5, 0, 1, 1, 1, 2, 3, 4, 24, 12, 5, 0, 7, + 23, 5, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 0, 0,128, 0, + 0, 0, 9, 11, 5, 0, 1, 0, 19, 15,120,121,122, 20, 10, 5, 0, 18, 7, + 21, 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 8, 9, 5, + 0, 1, 1, 1, 4, 2, 3, 24, 8, 5, 0, 5, 7, 23, 0, 0,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 8, 7, 4, 0, 19, + 1,120,121,122, 15, 20, 6, 5, 0, 21, 18, 7,102,111,117,114, 85,102,119, + 64, 12, 0, 0, 0, 0, 0, 0, 8, 5, 5, 0, 1, 1, 1, 3, 4, 2, 24, + 4, 5, 0, 23, 5, 7, 98,117, 98, 98, 97, 0, 0,128, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 3, 5, 0, 0, 19, 1,120,121,122, 15, 20, 2, + 5, 0, 7, 21, 18, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 85,102, + 119, 8, 1, 5, 0, 1, 1, 1, 2, 3, 4, 13, 0, 0, 0, 26, 0, 63, 0, + 1,245, 1,219, 1,209, 1,187, 1,177, 1,151, 1,141, 1,119, 1,108, 1, + 82, 1, 72, 1, 50, 1, 39, 1, 13, 1, 3, 0,237, 0,227, 0,201, 0,191, + 0,169, 0,158, 0,132, 0,122, 0,100, 0, 89, 0, 63, 0, 0, 0, 24, 52, + 5, 0, 7, 23, 5, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 0, + 0,128, 0, 0, 0, 9, 51, 5, 0, 1, 0, 19, 15,120,121,122, 20, 50, 5, + 0, 18, 7, 21, 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, + 8, 49, 5, 0, 1, 1, 1, 4, 2, 3, 24, 48, 5, 0, 23, 7, 5, 98,117, + 98, 98, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 9, 47, + 5, 0, 0, 1, 19, 15,120,121,122, 20, 46, 5, 0, 7, 18, 21, 64, 12, 0, + 0, 0, 0, 0, 0, 85,102,119,102,111,117,114, 8, 45, 5, 0, 1, 1, 1, + 2, 4, 3, 24, 44, 5, 0, 7, 5, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128, 0, 0, 0, 98,117, 98, 98, 97, 8, 43, 4, 0, 1, 19, 15,120,121, + 122, 20, 42, 5, 0, 18, 21, 7, 85,102,119,102,111,117,114, 64, 12, 0, 0, + 0, 0, 0, 0, 8, 41, 5, 0, 1, 1, 1, 4, 3, 2, 24, 40, 5, 0, 5, + 23, 7, 0, 0,128, 0, 0, 0, 98,117, 98, 98, 97, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 39, 5, 0, 19, 0, 1,120,121,122, 15, 20, 38, 5, 0, 21, 7, + 18,102,111,117,114, 64, 12, 0, 0, 0, 0, 0, 0, 85,102,119, 8, 37, 5, + 0, 1, 1, 1, 3, 2, 4, 24, 36, 5, 0, 23, 7, 5, 98,117, 98, 98, 97, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 9, 35, 5, 0, 0, + 1, 19, 15,120,121,122, 20, 34, 5, 0, 7, 18, 21, 64, 12, 0, 0, 0, 0, + 0, 0, 85,102,119,102,111,117,114, 8, 33, 5, 0, 1, 1, 1, 2, 4, 3, + 24, 32, 5, 0, 7, 5, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, + 0, 0, 98,117, 98, 98, 97, 8, 31, 4, 0, 1, 19, 15,120,121,122, 20, 30, + 5, 0, 18, 21, 7, 85,102,119,102,111,117,114, 64, 12, 0, 0, 0, 0, 0, + 0, 8, 29, 5, 0, 1, 1, 1, 4, 3, 2, 24, 28, 5, 0, 5, 23, 7, 0, + 0,128, 0, 0, 0, 98,117, 98, 98, 97, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 27, 5, 0, 19, 0, 1,120,121,122, 15, 13, 0, 0, 0, 12, 1, 50, 0, 1, + 246, 1,224, 1,213, 1,187, 1,177, 1,155, 1,145, 1,119, 1,109, 1, 87, + 1, 76, 1, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 64, 5, 0, 7, 23, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 0, 0,128, 0, 0, 0, + 9, 63, 5, 0, 1, 0, 19, 15,120,121,122, 20, 62, 5, 0, 18, 7, 21, 85, + 102,119, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 8, 61, 5, 0, 1, + 1, 1, 4, 2, 3, 24, 60, 5, 0, 5, 7, 23, 0, 0,128, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 8, 59, 4, 0, 19, 1,120, + 121,122, 15, 20, 58, 5, 0, 21, 18, 7,102,111,117,114, 85,102,119, 64, 12, + 0, 0, 0, 0, 0, 0, 8, 57, 5, 0, 1, 1, 1, 3, 4, 2, 24, 56, 5, + 0, 23, 5, 7, 98,117, 98, 98, 97, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 55, 5, 0, 0, 19, 1,120,121,122, 15, 20, 54, 5, 0, + 7, 21, 18, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 85,102,119, 8, + 53, 5, 0, 1, 1, 1, 2, 3, 4, 13, 0, 0, 0, 27, 0, 72, 0, 1,245, + 1,224, 1,212, 1,192, 1,181, 1,165, 1,152, 1,129, 1,118, 1, 97, 1, + 87, 1, 64, 1, 52, 1, 30, 1, 17, 0,252, 0,240, 0,223, 0,209, 0,185, + 0,173, 0,152, 0,141, 0,118, 0,106, 0, 84, 0, 72, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 27, 3, 21, 19,120, 50, 55,121,120,121,122, 20, 26, + 4, 21, 21, 7,120, 50, 54,121,102,111,117,114, 64, 12, 0, 0, 0, 0, 0, + 0, 10, 25, 4, 21, 1, 1,120, 50, 53,121, 3, 2, 21, 24, 4, 21, 23, 7, + 120, 50, 52,121, 98,117, 98, 98, 97, 0, 0, 0, 0, 0, 0, 0, 0, 9, 23, + 4, 21, 0, 1,120, 50, 51,121, 15, 19, 22, 4, 21, 7, 18,120, 50, 50,121, + 64, 12, 0, 0, 0, 0, 0, 0, 85,102,119, 10, 21, 4, 21, 1, 1,120, 50, + 49,121, 2, 4, 22, 20, 4, 21, 7, 5,120, 50, 48,121, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,128, 0, 0, 0, 12, 19, 4, 21, 1, 19,120, 49, 57,121, + 15,120,121,122, 15, 18, 4, 21, 18, 21,120, 49, 56,121, 85,102,119,102,111, + 117,114, 10, 17, 4, 21, 1, 1,120, 49, 55,121, 4, 3, 19, 16, 4, 21, 23, + 5,120, 49, 54,121, 98,117, 98, 98, 97, 0, 0,128, 0, 0, 0, 11, 15, 4, + 21, 0, 19,120, 49, 53,121,120,121,122, 20, 14, 4, 21, 7, 21,120, 49, 52, + 121, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 10, 13, 4, 21, 1, 1, + 120, 49, 51,121, 2, 3, 21, 12, 4, 21, 7, 23,120, 49, 50,121, 0, 0, 0, + 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 8, 11, 3, 21, 1,120, 49, 49,121, + 15, 19, 10, 4, 21, 18, 7,120, 49, 48,121, 85,102,119, 64, 12, 0, 0, 0, + 0, 0, 0, 9, 9, 4, 19, 1, 1,120, 57,121, 4, 2, 21, 8, 4, 19, 5, + 7,120, 56,121, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, + 7, 4, 19, 19, 1,120, 55,121,120,121,122, 15, 14, 6, 4, 19, 21, 18,120, + 54,121,102,111,117,114, 85,102,119, 9, 5, 4, 19, 1, 1,120, 53,121, 3, + 4, 18, 4, 4, 19, 23, 5,120, 52,121, 98,117, 98, 98, 97, 0, 0,128, 0, + 0, 0, 10, 3, 4, 19, 0, 19,120, 51,121,120,121,122, 19, 2, 4, 19, 7, + 21,120, 50,121, 64, 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 9, 1, 4, + 19, 1, 1,120, 49,121, 2, 3, 13, 0, 0, 0, 26, 0, 78, 0, 1,235, 1, + 223, 1,206, 1,192, 1,168, 1,156, 1,135, 1,124, 1,101, 1, 89, 1, 67, + 1, 55, 1, 34, 1, 22, 1, 5, 0,247, 0,223, 0,211, 0,190, 0,179, 0, + 156, 0,144, 0,123, 0,113, 0, 90, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 53, 4, 21, 1, 1,120, 53, 51, + 121, 2, 3, 21, 52, 4, 21, 7, 23,120, 53, 50,121, 0, 0, 0, 0, 0, 0, + 0, 0, 98,117, 98, 98, 97, 8, 51, 3, 21, 1,120, 53, 49,121, 15, 19, 50, + 4, 21, 18, 7,120, 53, 48,121, 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0, + 10, 49, 4, 21, 1, 1,120, 52, 57,121, 4, 2, 21, 48, 4, 21, 23, 7,120, + 52, 56,121, 98,117, 98, 98, 97, 0, 0, 0, 0, 0, 0, 0, 0, 9, 47, 4, + 21, 0, 1,120, 52, 55,121, 15, 19, 46, 4, 21, 7, 18,120, 52, 54,121, 64, + 12, 0, 0, 0, 0, 0, 0, 85,102,119, 10, 45, 4, 21, 1, 1,120, 52, 53, + 121, 2, 4, 22, 44, 4, 21, 7, 5,120, 52, 52,121, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,128, 0, 0, 0, 12, 43, 4, 21, 1, 19,120, 52, 51,121, 15, + 120,121,122, 15, 42, 4, 21, 18, 21,120, 52, 50,121, 85,102,119,102,111,117, + 114, 10, 41, 4, 21, 1, 1,120, 52, 49,121, 4, 3, 19, 40, 4, 21, 5, 23, + 120, 52, 48,121, 0, 0,128, 0, 0, 0, 98,117, 98, 98, 97, 10, 39, 3, 21, + 19,120, 51, 57,121,120,121,122, 20, 38, 4, 21, 21, 7,120, 51, 56,121,102, + 111,117,114, 64, 12, 0, 0, 0, 0, 0, 0, 10, 37, 4, 21, 1, 1,120, 51, + 55,121, 3, 2, 21, 36, 4, 21, 23, 7,120, 51, 54,121, 98,117, 98, 98, 97, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 35, 4, 21, 0, 1,120, 51, 53,121, 15, + 19, 34, 4, 21, 7, 18,120, 51, 52,121, 64, 12, 0, 0, 0, 0, 0, 0, 85, + 102,119, 10, 33, 4, 21, 1, 1,120, 51, 51,121, 2, 4, 22, 32, 4, 21, 7, + 5,120, 51, 50,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, + 12, 31, 4, 21, 1, 19,120, 51, 49,121, 15,120,121,122, 15, 30, 4, 21, 18, + 21,120, 51, 48,121, 85,102,119,102,111,117,114, 10, 29, 4, 21, 1, 1,120, + 50, 57,121, 4, 3, 19, 28, 4, 21, 5, 23,120, 50, 56,121, 0, 0,128, 0, + 0, 0, 98,117, 98, 98, 97, 13, 0, 0, 0, 11, 1, 67, 0, 1,234, 1,221, + 1,200, 1,188, 1,171, 1,157, 1,133, 1,121, 1,100, 1, 90, 1, 67, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, 64, 4, 21, 7, 23,120, 54, 52,121, 0, 0, + 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 8, 63, 3, 21, 1,120, 54, 51, + 121, 15, 19, 62, 4, 21, 18, 7,120, 54, 50,121, 85,102,119, 64, 12, 0, 0, + 0, 0, 0, 0, 10, 61, 4, 21, 1, 1,120, 54, 49,121, 4, 2, 22, 60, 4, + 21, 5, 7,120, 54, 48,121, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 12, 59, 4, 21, 19, 1,120, 53, 57,121,120,121,122, 15, 15, 58, 4, + 21, 21, 18,120, 53, 56,121,102,111,117,114, 85,102,119, 10, 57, 4, 21, 1, + 1,120, 53, 55,121, 3, 4, 19, 56, 4, 21, 23, 5,120, 53, 54,121, 98,117, + 98, 98, 97, 0, 0,128, 0, 0, 0, 11, 55, 4, 21, 0, 19,120, 53, 53,121, + 120,121,122, 20, 54, 4, 21, 7, 21,120, 53, 52,121, 64, 12, 0, 0, 0, 0, + 0, 0,102,111,117,114, 10, 0, 0, 0, 45, 0,112, 0, 1,247, 1,238, 1, + 229, 1,220, 1,211, 1,202, 1,193, 1,184, 1,175, 1,166, 1,159, 1,150, + 1,141, 1,132, 1,123, 1,114, 1,105, 1, 96, 1, 87, 1, 78, 1, 69, 1, + 61, 1, 52, 1, 43, 1, 34, 1, 25, 1, 16, 1, 7, 0,254, 0,245, 0,236, + 0,227, 0,219, 0,210, 0,201, 0,192, 0,183, 0,174, 0,165, 0,156, 0, + 147, 0,138, 0,129, 0,121, 0,112, 0,103, 0, 0, 0, 0, 0, 0, 9,120, + 53, 49,121, 51, 8, 3, 21, 1,120, 53, 48,121, 50, 7, 3, 19, 1,120, 52, + 121, 4, 8, 3, 21, 1,120, 52, 57,121, 49, 8, 3, 21, 1,120, 52, 56,121, + 48, 8, 3, 21, 1,120, 52, 55,121, 47, 8, 3, 21, 1,120, 52, 54,121, 46, + 8, 3, 21, 1,120, 52, 53,121, 45, 8, 3, 21, 1,120, 52, 52,121, 44, 8, + 3, 21, 1,120, 52, 51,121, 43, 8, 3, 21, 1,120, 52, 50,121, 42, 8, 3, + 21, 1,120, 52, 49,121, 41, 8, 3, 21, 1,120, 52, 48,121, 40, 7, 3, 19, + 1,120, 51,121, 3, 8, 3, 21, 1,120, 51, 57,121, 39, 8, 3, 21, 1,120, + 51, 56,121, 38, 8, 3, 21, 1,120, 51, 55,121, 37, 8, 3, 21, 1,120, 51, + 54,121, 36, 8, 3, 21, 1,120, 51, 53,121, 35, 8, 3, 21, 1,120, 51, 52, + 121, 34, 8, 3, 21, 1,120, 51, 51,121, 33, 8, 3, 21, 1,120, 51, 50,121, + 32, 8, 3, 21, 1,120, 51, 49,121, 31, 8, 3, 21, 1,120, 51, 48,121, 30, + 7, 3, 19, 1,120, 50,121, 2, 8, 3, 21, 1,120, 50, 57,121, 29, 8, 3, + 21, 1,120, 50, 56,121, 28, 8, 3, 21, 1,120, 50, 55,121, 27, 8, 3, 21, + 1,120, 50, 54,121, 26, 8, 3, 21, 1,120, 50, 53,121, 25, 8, 3, 21, 1, + 120, 50, 52,121, 24, 8, 3, 21, 1,120, 50, 51,121, 23, 8, 3, 21, 1,120, + 50, 50,121, 22, 8, 3, 21, 1,120, 50, 49,121, 21, 8, 3, 21, 1,120, 50, + 48,121, 20, 6, 3, 19, 9,120, 49,121, 8, 3, 21, 1,120, 49, 57,121, 19, + 8, 3, 21, 1,120, 49, 56,121, 18, 8, 3, 21, 1,120, 49, 55,121, 17, 8, + 3, 21, 1,120, 49, 54,121, 16, 8, 3, 21, 1,120, 49, 53,121, 15, 8, 3, + 21, 1,120, 49, 52,121, 14, 8, 3, 21, 1,120, 49, 51,121, 13, 8, 3, 21, + 1,120, 49, 50,121, 12, 8, 3, 21, 1,120, 49, 49,121, 11, 8, 3, 21, 1, + 120, 49, 48,121, 10, 10, 0, 0, 0, 18, 1, 99, 0, 1,247, 1,238, 1,229, + 1,220, 1,211, 1,202, 1,193, 1,184, 1,176, 1,167, 1,158, 1,149, 1, + 140, 1,131, 1,123, 1,115, 1,107, 1, 99, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, + 3, 19, 1,120, 57,121, 9, 7, 3, 19, 1,120, 56,121, 8, 7, 3, 19, 1, + 120, 55,121, 7, 7, 3, 19, 1,120, 54,121, 6, 8, 3, 21, 1,120, 54, 52, + 121, 64, 8, 3, 21, 1,120, 54, 51,121, 63, 8, 3, 21, 1,120, 54, 50,121, + 62, 8, 3, 21, 1,120, 54, 49,121, 61, 8, 3, 21, 1,120, 54, 48,121, 60, + 7, 3, 19, 1,120, 53,121, 5, 8, 3, 21, 1,120, 53, 57,121, 59, 8, 3, + 21, 1,120, 53, 56,121, 58, 8, 3, 21, 1,120, 53, 55,121, 57, 8, 3, 21, + 1,120, 53, 54,121, 56, 8, 3, 21, 1,120, 53, 53,121, 55, 8, 3, 21, 1, + 120, 53, 52,121, 54, 8, 3, 21, 1,120, 53, 51,121, 53, 8, 3, 21, 1,120, + 53, 50,121, 52, 13, 0, 0, 0, 23, 0, 54, 0, 1,240, 1,214, 1,197, 1, + 172, 1,156, 1,135, 1,117, 1, 89, 1, 73, 1, 55, 1, 41, 1, 14, 0,254, + 0,228, 0,211, 0,186, 0,170, 0,149, 0,131, 0,110, 0, 94, 0, 69, 0, + 54, 13, 23, 4, 7, 0, 1, 64, 57, 76,204,204,204,204,205, 15, 23, 22, 4, + 7, 7, 18, 64, 56, 51, 51, 51, 51, 51, 52, 64, 12, 0, 0, 0, 0, 0, 0, + 85,102,119, 14, 21, 4, 7, 1, 1, 64, 55, 25,153,153,153,153,154, 2, 4, + 19, 20, 4, 1, 7, 5, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, + 0, 0, 16, 19, 4, 7, 1, 19, 64, 52,230,102,102,102,102,103, 15,120,121, + 122, 19, 18, 4, 7, 18, 21, 64, 51,204,204,204,204,204,205, 85,102,119,102, + 111,117,114, 14, 17, 4, 7, 1, 1, 64, 50,179, 51, 51, 51, 51, 52, 4, 3, + 23, 16, 4, 7, 23, 5, 64, 49,153,153,153,153,153,154, 98,117, 98, 98, 97, + 0, 0,128, 0, 0, 0, 15, 15, 4, 7, 0, 19, 64, 48,128, 0, 0, 0, 0, + 0,120,121,122, 24, 14, 4, 7, 7, 21, 64, 46,204,204,204,204,204,206, 64, + 12, 0, 0, 0, 0, 0, 0,102,111,117,114, 14, 13, 4, 7, 1, 1, 64, 44, + 153,153,153,153,153,154, 2, 3, 25, 12, 4, 7, 7, 23, 64, 42,102,102,102, + 102,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 12, 11, 3, + 7, 1, 64, 40, 51, 51, 51, 51, 51, 52, 15, 16, 10, 4, 1, 18, 7, 11, 85, + 102,119, 64, 12, 0, 0, 0, 0, 0, 0, 14, 9, 4, 7, 1, 1, 64, 35,204, + 204,204,204,204,205, 4, 2, 26, 8, 4, 7, 5, 7, 64, 33,153,153,153,153, + 153,154, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 7, 4, + 7, 19, 1, 64, 30,204,204,204,204,204,206,120,121,122, 15, 19, 6, 4, 7, + 21, 18, 64, 26,102,102,102,102,102,103,102,111,117,114, 85,102,119, 14, 5, + 4, 7, 1, 1, 64, 22, 0, 0, 0, 0, 0, 0, 3, 4, 23, 4, 4, 7, 23, + 5, 64, 17,153,153,153,153,153,154, 98,117, 98, 98, 97, 0, 0,128, 0, 0, + 0, 15, 3, 4, 7, 0, 19, 64, 10,102,102,102,102,102,103,120,121,122, 24, + 2, 4, 7, 7, 21, 64, 1,153,153,153,153,153,154, 64, 12, 0, 0, 0, 0, + 0, 0,102,111,117,114, 14, 1, 4, 7, 1, 1, 63,241,153,153,153,153,153, + 154, 2, 3, 13, 0, 0, 0, 22, 0, 68, 0, 1,229, 1,213, 1,187, 1,171, + 1,146, 1,130, 1,116, 1, 98, 1, 70, 1, 54, 1, 29, 1, 14, 0,243, 0, + 227, 0,201, 0,185, 0,167, 0,151, 0,130, 0,112, 0, 84, 0, 68, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 45, 4, 7, 1, + 1, 64, 72,192, 0, 0, 0, 0, 1, 2, 4, 26, 44, 4, 7, 7, 5, 64, 72, + 51, 51, 51, 51, 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, + 0, 16, 43, 4, 7, 1, 19, 64, 71,166,102,102,102,102,103, 15,120,121,122, + 19, 42, 4, 7, 18, 21, 64, 71, 25,153,153,153,153,154, 85,102,119,102,111, + 117,114, 14, 41, 4, 7, 1, 1, 64, 70,140,204,204,204,204,205, 4, 3, 16, + 40, 4, 1, 5, 23, 44, 0, 0,128, 0, 0, 0, 98,117, 98, 98, 97, 14, 39, + 3, 7, 19, 64, 69,115, 51, 51, 51, 51, 52,120,121,122, 24, 38, 4, 7, 21, + 7, 64, 68,230,102,102,102,102,103,102,111,117,114, 64, 12, 0, 0, 0, 0, + 0, 0, 14, 37, 4, 7, 1, 1, 64, 68, 89,153,153,153,153,154, 3, 2, 25, + 36, 4, 7, 23, 7, 64, 67,204,204,204,204,204,205, 98,117, 98, 98, 97, 0, + 0, 0, 0, 0, 0, 0, 0, 13, 35, 4, 7, 0, 1, 64, 67, 64, 0, 0, 0, + 0, 0, 15, 23, 34, 4, 7, 7, 18, 64, 66,179, 51, 51, 51, 51, 52, 64, 12, + 0, 0, 0, 0, 0, 0, 85,102,119, 14, 33, 4, 7, 1, 1, 64, 66, 38,102, + 102,102,102,103, 2, 4, 26, 32, 4, 7, 7, 5, 64, 65,153,153,153,153,153, + 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 16, 31, 4, 7, + 1, 19, 64, 65, 12,204,204,204,204,205, 15,120,121,122, 12, 30, 4, 1, 18, + 21, 33, 85,102,119,102,111,117,114, 14, 29, 4, 7, 1, 1, 64, 63,230,102, + 102,102,102,103, 4, 3, 23, 28, 4, 7, 5, 23, 64, 62,204,204,204,204,204, + 206, 0, 0,128, 0, 0, 0, 98,117, 98, 98, 97, 14, 27, 3, 7, 19, 64, 61, + 179, 51, 51, 51, 51, 52,120,121,122, 24, 26, 4, 7, 21, 7, 64, 60,153,153, + 153,153,153,154,102,111,117,114, 64, 12, 0, 0, 0, 0, 0, 0, 14, 25, 4, + 7, 1, 1, 64, 59,128, 0, 0, 0, 0, 1, 3, 2, 25, 24, 4, 7, 23, 7, + 64, 58,102,102,102,102,102,103, 98,117, 98, 98, 97, 0, 0, 0, 0, 0, 0, + 0, 0, 13, 0, 0, 0, 19, 0,121, 0, 1,231, 1,216, 1,189, 1,173, 1, + 148, 1,134, 1,107, 1, 91, 1, 65, 1, 48, 1, 23, 1, 7, 0,242, 0,224, + 0,203, 0,187, 0,162, 0,148, 0,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 64, 4, 7, 7, 23, 64, 81,153,153, + 153,153,153,154, 0, 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 12, 63, + 3, 7, 1, 64, 81, 83, 51, 51, 51, 51, 52, 15, 23, 62, 4, 7, 18, 7, 64, + 81, 12,204,204,204,204,205, 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0, 14, + 61, 4, 7, 1, 1, 64, 80,198,102,102,102,102,103, 4, 2, 19, 60, 4, 1, + 5, 7, 66, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 59, + 4, 7, 19, 1, 64, 80, 57,153,153,153,153,154,120,121,122, 15, 19, 58, 4, + 7, 21, 18, 64, 79,230,102,102,102,102,103,102,111,117,114, 85,102,119, 14, + 57, 4, 7, 1, 1, 64, 79, 89,153,153,153,153,154, 3, 4, 23, 56, 4, 7, + 23, 5, 64, 78,204,204,204,204,204,206, 98,117, 98, 98, 97, 0, 0,128, 0, + 0, 0, 15, 55, 4, 7, 0, 19, 64, 78, 64, 0, 0, 0, 0, 1,120,121,122, + 24, 54, 4, 7, 7, 21, 64, 77,179, 51, 51, 51, 51, 52, 64, 12, 0, 0, 0, + 0, 0, 0,102,111,117,114, 14, 53, 4, 7, 1, 1, 64, 77, 38,102,102,102, + 102,103, 2, 3, 25, 52, 4, 7, 7, 23, 64, 76,153,153,153,153,153,154, 0, + 0, 0, 0, 0, 0, 0, 0, 98,117, 98, 98, 97, 12, 51, 3, 7, 1, 64, 76, + 12,204,204,204,204,205, 15, 23, 50, 4, 7, 18, 7, 64, 75,128, 0, 0, 0, + 0, 1, 85,102,119, 64, 12, 0, 0, 0, 0, 0, 0, 14, 49, 4, 7, 1, 1, + 64, 74,243, 51, 51, 51, 51, 52, 4, 2, 25, 48, 4, 7, 23, 7, 64, 74,102, + 102,102,102,102,103, 98,117, 98, 98, 97, 0, 0, 0, 0, 0, 0, 0, 0, 13, + 47, 4, 7, 0, 1, 64, 73,217,153,153,153,153,154, 15, 23, 46, 4, 7, 7, + 18, 64, 73, 76,204,204,204,204,205, 64, 12, 0, 0, 0, 0, 0, 0, 85,102, + 119, 10, 0, 0, 0, 34, 0, 92, 0, 1,244, 1,231, 1,218, 1,205, 1,192, + 1,179, 1,166, 1,153, 1,140, 1,134, 1,121, 1,108, 1, 95, 1, 82, 1, + 69, 1, 56, 1, 43, 1, 30, 1, 17, 1, 11, 0,254, 0,241, 0,228, 0,215, + 0,202, 0,189, 0,176, 0,163, 0,150, 0,144, 0,131, 0,118, 0,105, 0, + 92, 0, 79, 0, 0, 0, 0, 13, 64, 67, 64, 0, 0, 0, 0, 0, 35, 12, 3, + 7, 1, 64, 66,179, 51, 51, 51, 51, 52, 34, 12, 3, 7, 1, 64, 66, 38,102, + 102,102,102,103, 33, 12, 3, 7, 1, 64, 65,153,153,153,153,153,154, 32, 12, + 3, 7, 1, 64, 65, 12,204,204,204,204,205, 31, 5, 3, 1, 1, 33, 30, 12, + 3, 7, 1, 64, 63,230,102,102,102,102,103, 29, 12, 3, 7, 1, 64, 62,204, + 204,204,204,204,206, 28, 12, 3, 7, 1, 64, 61,179, 51, 51, 51, 51, 52, 27, + 12, 3, 7, 1, 64, 60,153,153,153,153,153,154, 26, 12, 3, 7, 1, 64, 59, + 128, 0, 0, 0, 0, 1, 25, 12, 3, 7, 1, 64, 58,102,102,102,102,102,103, + 24, 12, 3, 7, 1, 64, 57, 76,204,204,204,204,205, 23, 12, 3, 7, 1, 64, + 56, 51, 51, 51, 51, 51, 52, 22, 12, 3, 7, 1, 64, 55, 25,153,153,153,153, + 154, 21, 5, 3, 1, 1, 22, 20, 12, 3, 7, 1, 64, 52,230,102,102,102,102, + 103, 19, 12, 3, 7, 1, 64, 51,204,204,204,204,204,205, 18, 12, 3, 7, 1, + 64, 50,179, 51, 51, 51, 51, 52, 17, 12, 3, 7, 1, 64, 49,153,153,153,153, + 153,154, 16, 12, 3, 7, 1, 64, 48,128, 0, 0, 0, 0, 0, 15, 12, 3, 7, + 1, 64, 46,204,204,204,204,204,206, 14, 12, 3, 7, 1, 64, 44,153,153,153, + 153,153,154, 13, 12, 3, 7, 1, 64, 42,102,102,102,102,102,103, 12, 12, 3, + 7, 1, 64, 40, 51, 51, 51, 51, 51, 52, 11, 5, 3, 1, 1, 11, 10, 12, 3, + 7, 1, 64, 35,204,204,204,204,204,205, 9, 12, 3, 7, 1, 64, 33,153,153, + 153,153,153,154, 8, 12, 3, 7, 1, 64, 30,204,204,204,204,204,206, 7, 12, + 3, 7, 1, 64, 26,102,102,102,102,102,103, 6, 12, 3, 7, 1, 64, 22, 0, + 0, 0, 0, 0, 0, 5, 12, 3, 7, 1, 64, 17,153,153,153,153,153,154, 4, + 12, 3, 7, 1, 64, 10,102,102,102,102,102,103, 3, 12, 3, 7, 1, 64, 1, + 153,153,153,153,153,154, 2, 11, 3, 7, 9, 63,241,153,153,153,153,153,154, + 10, 0, 0, 0, 29, 0,149, 0, 1,243, 1,230, 1,217, 1,204, 1,198, 1, + 185, 1,172, 1,159, 1,146, 1,133, 1,120, 1,107, 1, 94, 1, 81, 1, 68, + 1, 55, 1, 42, 1, 29, 1, 16, 1, 3, 0,246, 0,233, 0,220, 0,207, 0, + 201, 0,188, 0,175, 0,162, 0,149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 7, + 1, 64, 81,153,153,153,153,153,154, 64, 12, 3, 7, 1, 64, 81, 83, 51, 51, + 51, 51, 52, 63, 12, 3, 7, 1, 64, 81, 12,204,204,204,204,205, 62, 12, 3, + 7, 1, 64, 80,198,102,102,102,102,103, 61, 5, 3, 1, 1, 66, 60, 12, 3, + 7, 1, 64, 80, 57,153,153,153,153,154, 59, 12, 3, 7, 1, 64, 79,230,102, + 102,102,102,103, 58, 12, 3, 7, 1, 64, 79, 89,153,153,153,153,154, 57, 12, + 3, 7, 1, 64, 78,204,204,204,204,204,206, 56, 12, 3, 7, 1, 64, 78, 64, + 0, 0, 0, 0, 1, 55, 12, 3, 7, 1, 64, 77,179, 51, 51, 51, 51, 52, 54, + 12, 3, 7, 1, 64, 77, 38,102,102,102,102,103, 53, 12, 3, 7, 1, 64, 76, + 153,153,153,153,153,154, 52, 12, 3, 7, 1, 64, 76, 12,204,204,204,204,205, + 51, 12, 3, 7, 1, 64, 75,128, 0, 0, 0, 0, 1, 50, 12, 3, 7, 1, 64, + 74,243, 51, 51, 51, 51, 52, 49, 12, 3, 7, 1, 64, 74,102,102,102,102,102, + 103, 48, 12, 3, 7, 1, 64, 73,217,153,153,153,153,154, 47, 12, 3, 7, 1, + 64, 73, 76,204,204,204,204,205, 46, 12, 3, 7, 1, 64, 72,192, 0, 0, 0, + 0, 1, 45, 12, 3, 7, 1, 64, 72, 51, 51, 51, 51, 51, 52, 44, 12, 3, 7, + 1, 64, 71,166,102,102,102,102,103, 43, 12, 3, 7, 1, 64, 71, 25,153,153, + 153,153,154, 42, 12, 3, 7, 1, 64, 70,140,204,204,204,204,205, 41, 5, 3, + 1, 1, 44, 40, 12, 3, 7, 1, 64, 69,115, 51, 51, 51, 51, 52, 39, 12, 3, + 7, 1, 64, 68,230,102,102,102,102,103, 38, 12, 3, 7, 1, 64, 68, 89,153, + 153,153,153,154, 37, 12, 3, 7, 1, 64, 67,204,204,204,204,204,205, 36, 10, + 0, 0, 0, 41, 0,103, 0, 1,250, 1,235, 1,227, 1,218, 1,211, 1,202, + 1,192, 1,179, 1,172, 1,157, 1,149, 1,141, 1,132, 1,125, 1,116, 1, + 106, 1, 93, 1, 86, 1, 74, 1, 63, 1, 47, 1, 40, 1, 31, 1, 16, 1, 8, + 0,255, 0,248, 0,239, 0,229, 0,216, 0,209, 0,197, 0,186, 0,174, 0, + 158, 0,151, 0,136, 0,128, 0,119, 0,112, 0,103, 0, 93, 0, 0, 0, 0, + 10, 55, 44, 78, 85, 76, 76, 8, 2, 25, 52, 54, 44, 51, 46, 53, 6, 2, 21, + 52, 53, 44, 50, 8, 2, 25, 52, 52, 44, 48, 46, 48, 7, 2, 23, 52, 51, 44, + 49, 53, 14, 2, 37, 52, 50, 44, 88, 39, 53, 53, 54, 54, 55, 55, 39, 6, 2, + 21, 52, 49, 44, 52, 15, 2, 39, 52, 48, 44, 50, 49, 52, 55, 52, 56, 51, 54, + 52, 56, 11, 2, 31, 52, 44, 39, 98,117, 98, 98, 97, 39, 10, 2, 29, 51, 57, + 44, 39,120,121,122, 39, 11, 2, 31, 51, 56, 44, 39,102,111,117,114, 39, 6, + 2, 21, 51, 55, 44, 51, 12, 2, 33, 51, 54, 44, 39, 98,117, 98, 98, 97, 39, + 9, 2, 27, 51, 53, 44, 78, 85, 76, 76, 8, 2, 25, 51, 52, 44, 51, 46, 53, + 6, 2, 21, 51, 51, 44, 50, 8, 2, 25, 51, 50, 44, 48, 46, 48, 7, 2, 23, + 51, 49, 44, 49, 53, 14, 2, 37, 51, 48, 44, 88, 39, 53, 53, 54, 54, 55, 55, + 39, 8, 2, 25, 51, 44, 78, 85, 76, 76, 6, 2, 21, 50, 57, 44, 52, 15, 2, + 39, 50, 56, 44, 50, 49, 52, 55, 52, 56, 51, 54, 52, 56, 10, 2, 29, 50, 55, + 44, 39,120,121,122, 39, 11, 2, 31, 50, 54, 44, 39,102,111,117,114, 39, 6, + 2, 21, 50, 53, 44, 51, 12, 2, 33, 50, 52, 44, 39, 98,117, 98, 98, 97, 39, + 9, 2, 27, 50, 51, 44, 78, 85, 76, 76, 8, 2, 25, 50, 50, 44, 51, 46, 53, + 6, 2, 21, 50, 49, 44, 50, 8, 2, 25, 50, 48, 44, 48, 46, 48, 7, 2, 23, + 50, 44, 51, 46, 53, 7, 2, 23, 49, 57, 44, 49, 53, 14, 2, 37, 49, 56, 44, + 88, 39, 53, 53, 54, 54, 55, 55, 39, 6, 2, 21, 49, 55, 44, 52, 12, 2, 33, + 49, 54, 44, 39, 98,117, 98, 98, 97, 39, 9, 2, 27, 49, 53, 44, 78, 85, 76, + 76, 8, 2, 25, 49, 52, 44, 51, 46, 53, 6, 2, 21, 49, 51, 44, 50, 8, 2, + 25, 49, 50, 44, 48, 46, 48, 7, 2, 23, 49, 49, 44, 49, 53, 14, 2, 37, 49, + 48, 44, 88, 39, 53, 53, 54, 54, 55, 55, 39, 5, 2, 19, 49, 44, 50, 10, 0, + 0, 0, 22, 1, 32, 0, 1,243, 1,236, 1,230, 1,215, 1,207, 1,198, 1, + 191, 1,182, 1,172, 1,159, 1,152, 1,140, 1,129, 1,118, 1,102, 1, 95, + 1, 80, 1, 72, 1, 63, 1, 53, 1, 38, 1, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 2, 19, 57, 44, 52, 14, 2, 37, 56, 44, 50, 49, 52, 55, 52, 56, 51, + 54, 52, 56, 9, 2, 27, 55, 44, 39,120,121,122, 39, 8, 2, 25, 54, 52, 44, + 48, 46, 48, 7, 2, 23, 54, 51, 44, 49, 53, 14, 2, 37, 54, 50, 44, 88, 39, + 53, 53, 54, 54, 55, 55, 39, 6, 2, 21, 54, 49, 44, 52, 15, 2, 39, 54, 48, + 44, 50, 49, 52, 55, 52, 56, 51, 54, 52, 56, 10, 2, 29, 54, 44, 39,102,111, + 117,114, 39, 10, 2, 29, 53, 57, 44, 39,120,121,122, 39, 11, 2, 31, 53, 56, + 44, 39,102,111,117,114, 39, 6, 2, 21, 53, 55, 44, 51, 12, 2, 33, 53, 54, + 44, 39, 98,117, 98, 98, 97, 39, 9, 2, 27, 53, 53, 44, 78, 85, 76, 76, 8, + 2, 25, 53, 52, 44, 51, 46, 53, 6, 2, 21, 53, 51, 44, 50, 8, 2, 25, 53, + 50, 44, 48, 46, 48, 7, 2, 23, 53, 49, 44, 49, 53, 14, 2, 37, 53, 48, 44, + 88, 39, 53, 53, 54, 54, 55, 55, 39, 5, 2, 19, 53, 44, 51, 6, 2, 21, 52, + 57, 44, 52, 12, 2, 33, 52, 56, 44, 39, 98,117, 98, 98, 97, 39, +}; + +/* Help message */ +static const char zHelp[] = + "Usage:\n" + " sessionfuzz setup -- Generate seed files c1.txt, c2.txt, etc.\n" + " sessionfuzz run FILE ... -- Run against fuzzed changeset FILE\n" + " sessionfuzz run SQLAR ... -- Run against all files in the SQL Archive\n" +; + +#include +#include +#include +#include "zlib.h" + +/* +** Implementation of the "sqlar_uncompress(X,SZ)" SQL function +** +** Parameter SZ is interpreted as an integer. If it is less than or +** equal to zero, then this function returns a copy of X. Or, if +** SZ is equal to the size of X when interpreted as a blob, also +** return a copy of X. Otherwise, decompress blob X using zlib +** utility function uncompress() and return the results (another +** blob). +*/ +static void sqlarUncompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + uLong nData; + uLongf sz; + + assert( argc==2 ); + sz = sqlite3_value_int(argv[1]); + + if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ + sqlite3_result_value(context, argv[0]); + }else{ + const Bytef *pData= sqlite3_value_blob(argv[0]); + Bytef *pOut = sqlite3_malloc(sz); + if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){ + sqlite3_result_error(context, "error in uncompress()", -1); + }else{ + sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); + } + sqlite3_free(pOut); + } +} + + +/* Run a chunk of SQL. If any errors happen, print an error message +** and exit. +*/ +static void runSql(sqlite3 *db, const char *zSql){ + int rc; + char *zErr = 0; + rc = sqlite3_exec(db, zSql, 0, 0, &zErr); + if( rc || zErr ){ + fprintf(stderr, "SQL failed: rc=%d zErr=[%s]\n", rc, zErr); + fprintf(stderr, "SQL: [%s]\n", zSql); + exit(1); + } +} + +/* +** Write buffer to disk +*/ +static void writeFile(const char *zFilename, const void *pData, int nData){ + FILE *out; + int n; + out = fopen(zFilename, "wb"); + if( out==0 ){ + fprintf(stderr, "cannot open \"%s\" for writing\n", zFilename); + exit(1); + } + n = (int)fwrite(pData, 1, nData, out); + fclose(out); + if( n!=nData ){ + fprintf(stderr, "only wrote %d of %d bytes to \"%s\"\n",n,nData,zFilename); + exit(1); + } +} + +/* +** Generate a changeset from session pSess and write it to zFile +*/ +static void makeChangeset(const char *zFile, sqlite3_session *pSess){ + void *pChg; + int nChg; + int rc; + rc = sqlite3session_changeset(pSess, &nChg, &pChg); + if( rc ){ + fprintf(stderr, "sqlite3session_changeset() returned %d\n", rc); + exit(1); + } + writeFile(zFile, pChg, nChg); + sqlite3_free(pChg); +} + +/* +** Read a file from disk. Space to hold the answer is obtained from +** sqlite3_malloc64(). +*/ +static void readFile(const char *zName, void **ppData, int *pnData){ + FILE *in = fopen(zName, "rb"); + long nIn; + size_t nRead; + char *pBuf; + *ppData = 0; + *pnData = 0; + if( in==0 ){ + fprintf(stderr, "Cannot open \"%s\" for reading\n", zName); + exit(1); + } + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc64( nIn+1 ); + if( pBuf==0 ){ + fprintf(stderr, "Failed to malloc %lld bytes\n", (sqlite3_int64)(nIn+1)); + exit(1); + } + nRead = fread(pBuf, 1, nIn, in); + fclose(in); + if( nRead!=(size_t)nIn ){ + fprintf(stderr, "Read only %d of %d bytes from %s\n", (int)nRead, (int)nIn, + zName); + exit(1); + } + pBuf[nIn] = 0; + *pnData = nIn; + *ppData = pBuf; +} + +/* +** The conflict callback +*/ +static int conflictCall( + void *NotUsed, + int eConflict, + sqlite3_changeset_iter *p +){ + (void)NotUsed; + (void)p; + printf("Conflict %d\n", eConflict); + return SQLITE_CHANGESET_OMIT; +} + +/* +** Reset the database file +*/ +static void db_reset(sqlite3 *db){ + unsigned char *pData; + int nData; + int rc; + + nData = sizeof(aDbBytes); + pData = sqlite3_malloc64( nData ); + if( pData==0 ){ + fprintf(stderr, "could not allocate %d bytes\n", nData); + exit(1); + } + memcpy(pData, aDbBytes, nData); + rc = sqlite3_deserialize(db, 0, pData, nData, nData, + SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE); + if( rc ){ + fprintf(stderr, "sqlite3_deserialize() failed with %d: %s\n", + rc, sqlite3_errmsg(db)); + exit(1); + } +} + +/* +** Given a full file pathname, return a pointer to the tail. +** Example: +** +** input: /home/drh/sqlite/abc.db +** output: abc.db +*/ +static const char *fileTail(const char *z){ + const char *zOut = z; + while( z[0] ){ + if( z[0]=='/' && z[1]!=0 ) zOut = &z[1]; + z++; + } + return zOut; +} + +int main(int argc, char **argv){ + const char *zCmd; + sqlite3 *db; + int rc; + sqlite3_session *pSess; + sqlite3_stmt *pStmt; + void *pChgset; + int nChgset; + int bVerbose = 0; + + if( argc<2 ){ + fprintf(stderr, "%s", zHelp); + exit(1); + } + rc = sqlite3_open_v2(":memory:",&db, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "memdb"); + if( rc ){ + fprintf(stderr, "Failed to open :memory: database: %s\n", + sqlite3_errmsg(db)); + exit(1); + } + db_reset(db); + zCmd = argv[1]; + if( strcmp(zCmd, "setup")==0 ){ + if( argc!=2 ){ + fprintf(stdout, "Wrong number of arguments.\n%s", zHelp); + exit(1); + } + runSql(db, zFillSql); + rc = sqlite3session_create(db, "main", &pSess); + if( rc ){ + fprintf(stderr, "sqlite3session_create() returns %d\n", rc); + exit(1); + } + rc = sqlite3session_attach(pSess, 0); + if( rc ){ + fprintf(stderr, "sqlite3session_attach(db,0) returns %d\n", rc); + exit(1); + } + runSql(db, "INSERT INTO t4(z) VALUES('');"); + makeChangeset("c1.txt", pSess); + runSql(db, + "UPDATE t1 SET b=c, c=b WHERE a IN (5,7);\n" + "DELETE FROM t2 WHERE rowid IN (8,2);\n" + "INSERT OR IGNORE INTO t4 SELECT b FROM t1 WHERE b IS TRUE LIMIT 2;"); + makeChangeset("c2.txt", pSess); + runSql(db, "UPDATE t3 SET x=y, y=NULL WHERE rowid IN (1,3);"); + makeChangeset("c3.txt", pSess); + sqlite3session_delete(pSess); + }else + if( strcmp(zCmd, "run")==0 ){ + int i; + if( argc<3 ){ + fprintf(stdout, "Wrong number of arguments.\n%s", zHelp); + exit(1); + } + for(i=2; i= 512 + && memcmp(pChgset, "SQLite format 3", 16)==0 + ){ + sqlite3 *db2; + sqlite3_stmt *pStmt2; + int nCase = 0; + /* This file is an SQL Archive containing many changesets */ + if( !bVerbose ){ printf("%s: ", fileTail(argv[i])); fflush(stdout); } + sqlite3_open_v2(":memory:", &db2, + SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE, "memdb"); + sqlite3_deserialize(db2, 0, pChgset, nChgset, nChgset, + SQLITE_DESERIALIZE_READONLY | SQLITE_DESERIALIZE_FREEONCLOSE); + sqlite3_create_function(db2, "sqlar_uncompress", 2, SQLITE_UTF8, 0, + sqlarUncompressFunc, 0, 0); + rc = sqlite3_prepare_v2(db2, "SELECT name, sqlar_uncompress(data,sz)" + " FROM sqlar", -1, &pStmt2, 0); + if( rc ){ + fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db2)); + exit(1); + } + while( SQLITE_ROW==sqlite3_step(pStmt2) ){ + if( bVerbose ){ + printf("%s/%s:", fileTail(argv[i]), sqlite3_column_text(pStmt2,0)); + fflush(stdout); + } + runSql(db, "BEGIN"); + pChgset = (unsigned char*)sqlite3_column_blob(pStmt2, 1); + nChgset = sqlite3_column_bytes(pStmt2, 1); + rc = sqlite3changeset_apply(db, nChgset, pChgset, 0, conflictCall, 0); + if( bVerbose ){ + printf(" Ok. rc=%d\n", rc); + fflush(stdout); + } + runSql(db, "ROLLBACK"); + nCase++; + } + sqlite3_finalize(pStmt2); + sqlite3_close(db2); + if( bVerbose ) printf("%s: ", fileTail(argv[i])); + printf(" %d cases, 0 crashes\n", nCase); + fflush(stdout); + }else{ + /* The named file is just an ordinary changeset */ + printf("%s:", fileTail(argv[i])); + fflush(stdout); + runSql(db, "BEGIN"); + rc = sqlite3changeset_apply(db, nChgset, pChgset, 0, conflictCall, 0); + printf(" %d\n", rc); + fflush(stdout); + runSql(db, "ROLLBACK"); + sqlite3_free(pChgset); + } + } + }else + { + fprintf(stderr, "%s", zHelp); + exit(1); + } + rc = sqlite3_prepare_v2(db, "PRAGMA integrity_check;", -1, &pStmt, 0); + if( rc ){ + fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); + exit(1); + } + if( sqlite3_step(pStmt)!=SQLITE_ROW + || strcmp((const char*)sqlite3_column_text(pStmt,0),"ok")!=0 + ){ + fprintf(stderr, "Integrity check failed!\n"); + do{ + fprintf(stderr, "%s\n", sqlite3_column_text(pStmt,0)); + }while( sqlite3_step(pStmt)==SQLITE_ROW ); + } + sqlite3_finalize(pStmt); + sqlite3_close(db); + if( sqlite3_memory_used()>0 ){ + fprintf(stderr, "memory leak of %lld bytes\n", + sqlite3_memory_used()); + exit(1); + } + return 0; +} diff --git a/test/sharedA.test b/test/sharedA.test index 146fb26be0..55ed5749bb 100644 --- a/test/sharedA.test +++ b/test/sharedA.test @@ -19,6 +19,11 @@ if {[run_thread_tests]==0} { finish_test ; return } db close set ::testprefix sharedA +if {[atomic_batch_write test.db]} { + finish_test + return +} + set ::enable_shared_cache [sqlite3_enable_shared_cache 1] #------------------------------------------------------------------------- diff --git a/test/shell1.test b/test/shell1.test index ddd72c7180..aaf7addf5c 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -256,7 +256,7 @@ do_test shell1-3.1.3 { do_test shell1-3.1.4 { # too many arguments catchcmd "test.db" ".backup FOO BAR BAD" -} {1 {too many arguments to .backup}} +} {1 {Usage: .backup ?DB? ?--append? FILENAME}} # .bail ON|OFF Stop after hitting an error. Default OFF do_test shell1-3.2.1 { @@ -378,7 +378,7 @@ do_test shell1-3.10.1 { } {1 1 1} do_test shell1-3.10.2 { # we allow .help to take extra args (it is help after all) - set res [catchcmd "test.db" ".help BAD"] + set res [catchcmd "test.db" ".help *"] # look for a few of the possible help commands list [regexp {.help} $res] \ [regexp {.quit} $res] \ @@ -495,7 +495,7 @@ do_test shell1-3.15.2 { do_test shell1-3.15.3 { # too many arguments catchcmd "test.db" ".output FOO BAD" -} {1 {Usage: .output FILE}} +} {1 {Usage: .output [-e|-x|FILE]}} # .output stdout Send output to the screen do_test shell1-3.16.1 { @@ -504,7 +504,7 @@ do_test shell1-3.16.1 { do_test shell1-3.16.2 { # too many arguments catchcmd "test.db" ".output stdout BAD" -} {1 {Usage: .output FILE}} +} {1 {Usage: .output [-e|-x|FILE]}} # .prompt MAIN CONTINUE Replace the standard prompts do_test shell1-3.17.1 { @@ -581,8 +581,10 @@ do_test shell1-3.21.4 { } catchcmd "test.db" ".schema" } {0 {CREATE TABLE t1(x); -CREATE VIEW v2 AS SELECT x+1 AS y FROM t1; -CREATE VIEW v1 AS SELECT y+1 FROM v2;}} +CREATE VIEW v2 AS SELECT x+1 AS y FROM t1 +/* v2(y) */; +CREATE VIEW v1 AS SELECT y+1 FROM v2 +/* v1("y+1") */;}} db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;} } @@ -635,6 +637,19 @@ do_test shell1-3.23b.4 { catchcmd "test.db" ".stats OFF BAD" } {1 {Usage: .stats ?on|off?}} +# Ticket 7be932dfa60a8a6b3b26bcf7623ec46e0a403ddb 2018-06-07 +# Adverse interaction between .stats and .eqp +# +do_test shell1-3.23b.5 { + catchcmd "test.db" [string map {"\n " "\n"} { + CREATE TEMP TABLE t1(x); + INSERT INTO t1 VALUES(1),(2); + .stats on + .eqp full + SELECT * FROM t1; + }] +} {/1\n2\n/} + # .tables ?TABLE? List names of tables # If TABLE specified, only list tables matching # LIKE pattern TABLE. @@ -1095,4 +1110,46 @@ do_test shell1-6.1 { } {} } +db close +forcedelete test.db test.db-journal test.db-wal +sqlite3 db test.db + +# The shell tool ".schema" command uses virtual table "pragma_database_list" +# +ifcapable vtab { + +do_test shell1-7.1.1 { + db eval { + CREATE TABLE Z (x TEXT PRIMARY KEY); + CREATE TABLE _ (x TEXT PRIMARY KEY); + CREATE TABLE YY (x TEXT PRIMARY KEY); + CREATE TABLE __ (x TEXT PRIMARY KEY); + CREATE TABLE WWW (x TEXT PRIMARY KEY); + CREATE TABLE ___ (x TEXT PRIMARY KEY); + } +} {} +do_test shell1-7.1.2 { + catchcmd "test.db" ".schema _" +} {0 {CREATE TABLE Z (x TEXT PRIMARY KEY); +CREATE TABLE _ (x TEXT PRIMARY KEY);}} +do_test shell1-7.1.3 { + catchcmd "test.db" ".schema \\\\_" +} {0 {CREATE TABLE _ (x TEXT PRIMARY KEY);}} +do_test shell1-7.1.4 { + catchcmd "test.db" ".schema __" +} {0 {CREATE TABLE YY (x TEXT PRIMARY KEY); +CREATE TABLE __ (x TEXT PRIMARY KEY);}} +do_test shell1-7.1.5 { + catchcmd "test.db" ".schema \\\\_\\\\_" +} {0 {CREATE TABLE __ (x TEXT PRIMARY KEY);}} +do_test shell1-7.1.6 { + catchcmd "test.db" ".schema ___" +} {0 {CREATE TABLE WWW (x TEXT PRIMARY KEY); +CREATE TABLE ___ (x TEXT PRIMARY KEY);}} +do_test shell1-7.1.7 { + catchcmd "test.db" ".schema \\\\_\\\\_\\\\_" +} {0 {CREATE TABLE ___ (x TEXT PRIMARY KEY);}} + +} + finish_test diff --git a/test/shell3.test b/test/shell3.test index bb2524c1cc..63c30a2682 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -66,7 +66,7 @@ do_test shell3-1.6 { } {0 {}} do_test shell3-1.7 { catchcmd "foo.db \"CREATE TABLE\"" -} {1 {Error: near "TABLE": syntax error}} +} {1 {Error: incomplete input}} #---------------------------------------------------------------------------- # shell3-2.*: Basic tests for running SQL file from command line. @@ -96,6 +96,6 @@ do_test shell3-2.6 { } {0 {}} do_test shell3-2.7 { catchcmd "foo.db" "CREATE TABLE" -} {1 {Error: near line 1: near "TABLE": syntax error}} +} {1 {Error: near line 1: incomplete input}} finish_test diff --git a/test/shell6.test b/test/shell6.test index 25bfa32338..49b4cc3344 100644 --- a/test/shell6.test +++ b/test/shell6.test @@ -93,6 +93,14 @@ foreach {tn schema output} { } { } + 10 { + CREATE TABLE parent (id INTEGER PRIMARY KEY); + CREATE TABLE child2 (id INT PRIMARY KEY, parentID INT REFERENCES parent) + WITHOUT ROWID; + } { + CREATE INDEX 'child2_parentID' ON 'child2'('parentID'); --> parent(id) + } + } { forcedelete test.db sqlite3 db test.db diff --git a/test/shell8.test b/test/shell8.test new file mode 100644 index 0000000000..3658a8ac5d --- /dev/null +++ b/test/shell8.test @@ -0,0 +1,177 @@ +# 2017 December 9 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test the shell tool ".ar" command. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix shell8 + +ifcapable !vtab { + finish_test; return +} +set CLI [test_find_cli] + +# Check to make sure the shell has been compiled with ".archive" support. +# +if {[string match {*unknown command*} [catchcmd :memory: .archive]]} { + finish_test; return +} + +proc populate_dir {dirname spec} { + # First delete the current tree, if one exists. + file delete -force $dirname + + # Recreate the root of the new tree. + file mkdir $dirname + + # Add each file to the new tree. + foreach {f d} $spec { + set path [file join $dirname $f] + file mkdir [file dirname $path] + set fd [open $path w] + puts -nonewline $fd $d + close $fd + } +} + +proc dir_to_list {dirname {n -1}} { + if {$n<0} {set n [llength [file split $dirname]]} + + set res [list] + foreach f [glob -nocomplain $dirname/*] { + set mtime [file mtime $f] + if {$::tcl_platform(platform)!="windows"} { + set perm [file attributes $f -perm] + } else { + set perm 0 + } + set relpath [file join {*}[lrange [file split $f] $n end]] + lappend res + if {[file isdirectory $f]} { + lappend res [list $relpath / $mtime $perm] + lappend res {*}[dir_to_list $f] + } else { + set fd [open $f] + set data [read $fd] + close $fd + lappend res [list $relpath $data $mtime $perm] + } + } + lsort $res +} + +proc dir_compare {d1 d2} { + set l1 [dir_to_list $d1] + set l2 [dir_to_list $d1] + string compare $l1 $l2 +} + +foreach {tn tcl} { + 1 { + set c1 ".ar c ar1" + set x1 ".ar x" + + set c2 ".ar cC ar1 ." + set x2 ".ar Cx ar3" + + set c3 ".ar cCf ar1 test_xyz.db ." + set x3 ".ar Cfx ar3 test_xyz.db" + } + + 2 { + set c1 ".ar -c ar1" + set x1 ".ar -x" + + set c2 ".ar -cC ar1 ." + set x2 ".ar -xC ar3" + + set c3 ".ar -cCar1 -ftest_xyz.db ." + set x3 ".ar -x -C ar3 -f test_xyz.db" + } + + 3 { + set c1 ".ar --create ar1" + set x1 ".ar --extract" + + set c2 ".ar --directory ar1 --create ." + set x2 ".ar --extract --dir ar3" + + set c3 ".ar --creat --dir ar1 --file test_xyz.db ." + set x3 ".ar --e --dir ar3 --f test_xyz.db" + } + + 4 { + set c1 ".ar --cr ar1" + set x1 ".ar --e" + + set c2 ".ar -C ar1 -c ." + set x2 ".ar -x -C ar3" + + set c3 ".ar -c --directory ar1 --file test_xyz.db ." + set x3 ".ar -x --directory ar3 --file test_xyz.db" + } +} { + eval $tcl + + # Populate directory "ar1" with some files. + # + populate_dir ar1 { + file1 "abcd" + file2 "efgh" + dir1/file3 "ijkl" + } + set expected [dir_to_list ar1] + + do_test 1.$tn.1 { + catchcmd test_ar.db $c1 + file delete -force ar1 + catchcmd test_ar.db $x1 + dir_to_list ar1 + } $expected + + do_test 1.$tn.2 { + file delete -force ar3 + catchcmd test_ar.db $c2 + catchcmd test_ar.db $x2 + dir_to_list ar3 + } $expected + + do_test 1.$tn.3 { + file delete -force ar3 + file delete -force test_xyz.db + catchcmd ":memory:" $c3 + catchcmd ":memory:" $x3 + dir_to_list ar3 + } $expected + + # This is a repeat of test 1.$tn.1, except that there is a 2 second + # pause between creating the archive and extracting its contents. + # This is to test that timestamps are set correctly. + # + # Because it is slow, only do this for $tn==1. + if {$tn==1} { + do_test 1.$tn.1 { + catchcmd test_ar.db $c1 + file delete -force ar1 + after 2000 + catchcmd test_ar.db $x1 + dir_to_list ar1 + } $expected + } +} + +finish_test + + + +finish_test diff --git a/test/skipscan1.test b/test/skipscan1.test index 6cdeed5439..aca5c91ec0 100644 --- a/test/skipscan1.test +++ b/test/skipscan1.test @@ -337,4 +337,12 @@ do_execsql_test skipscan1-9.2 { SELECT * FROM t9a WHERE b IN (SELECT x FROM t9b WHERE y!=5); } {/USING INDEX t9a_ab .ANY.a. AND b=./} + +optimization_control db skip-scan 0 +do_execsql_test skipscan1-9.3 { + EXPLAIN QUERY PLAN + SELECT * FROM t9a WHERE b IN (SELECT x FROM t9b WHERE y!=5); +} {/{SCAN TABLE t9a}/} +optimization_control db skip-scan 1 + finish_test diff --git a/test/skipscan2.test b/test/skipscan2.test index a42ff2d057..df526b1dd3 100644 --- a/test/skipscan2.test +++ b/test/skipscan2.test @@ -199,7 +199,7 @@ do_test skipscan2-3.2 { } {} do_eqp_test skipscan2-3.3eqp { SELECT * FROM t3 WHERE b=42; -} {0 0 0 {SEARCH TABLE t3 USING PRIMARY KEY (ANY(a) AND b=?)}} +} {SEARCH TABLE t3 USING PRIMARY KEY (ANY(a) AND b=?)} finish_test diff --git a/test/skipscan6.test b/test/skipscan6.test index 026c4d7b00..a53be1d952 100644 --- a/test/skipscan6.test +++ b/test/skipscan6.test @@ -179,22 +179,13 @@ do_execsql_test 3.0 { # do_eqp_test 3.1 { SELECT * FROM t3 WHERE a = ? AND c = ? -} { - 0 0 0 {SEARCH TABLE t3 USING INDEX t3_a (a=?)} -} +} {SEARCH TABLE t3 USING INDEX t3_a (a=?)} # The same query on table t2. This should use index "t2_a", for the # same reason. At one point though, it was mistakenly using a skip-scan. # do_eqp_test 3.2 { SELECT * FROM t2 WHERE a = ? AND c = ? -} { - 0 0 0 {SEARCH TABLE t2 USING INDEX t2_a (a=?)} -} - -finish_test - - - +} {SEARCH TABLE t2 USING INDEX t2_a (a=?)} finish_test diff --git a/test/snapshot.test b/test/snapshot.test index 99d3ed47c3..75a8af214a 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -217,9 +217,19 @@ foreach {tn tcl} { SELECT * FROM t2; } } {a b c d e f} - do_test $tn.3.2.2 { - list [catch {snapshot_open db main $snapshot } msg] $msg + + # Update - it is no longer an error to have a read-transaction open, + # provided there are no active SELECT statements. + do_test $tn.3.2.2a { + db eval "SELECT * FROM t2" { + set res [list [catch {snapshot_open db main $snapshot } msg] $msg] + break + } + set res } {1 SQLITE_ERROR} + do_test $tn.3.2.2b { + snapshot_open db main $snapshot + } {} do_test $tn.3.2.3 { execsql { @@ -231,19 +241,24 @@ foreach {tn tcl} { } {1 SQLITE_ERROR} do_execsql_test $tn.3.2.4 COMMIT - do_test $tn.3.3.1 { + do_test $tn.3.3.1a { execsql { PRAGMA journal_mode = DELETE } execsql { BEGIN } list [catch {snapshot_open db main $snapshot } msg] $msg } {1 SQLITE_ERROR} + do_test $tn.3.3.1b { + execsql { COMMIT ; BEGIN ; SELECT * FROM t2 } + list [catch {snapshot_open db main $snapshot } msg] $msg + } {1 SQLITE_ERROR} + do_test $tn.$tn.3.3.2 { snapshot_free $snapshot execsql COMMIT } {} #------------------------------------------------------------------------- - # Check that SQLITE_BUSY_SNAPSHOT is returned if the specified snapshot + # Check that SQLITE_ERROR_SNAPSHOT is returned if the specified snapshot # no longer exists because the wal file has been checkpointed. # # 1. Reading a snapshot from the middle of a wal file is not possible @@ -281,7 +296,7 @@ foreach {tn tcl} { BEGIN; } list [catch {snapshot_open db main $snapshot} msg] $msg - } {1 SQLITE_BUSY_SNAPSHOT} + } {1 SQLITE_ERROR_SNAPSHOT} do_test $tn.4.1.4 { snapshot_free $snapshot execsql COMMIT @@ -312,7 +327,7 @@ foreach {tn tcl} { BEGIN; } list [catch {snapshot_open db main $snapshot} msg] $msg - } {1 SQLITE_BUSY_SNAPSHOT} + } {1 SQLITE_ERROR_SNAPSHOT} do_test $tn.4.2.4 { snapshot_free $snapshot } {} diff --git a/test/snapshot2.test b/test/snapshot2.test index 41e555258b..0f0e63961f 100644 --- a/test/snapshot2.test +++ b/test/snapshot2.test @@ -110,7 +110,7 @@ do_test 2.2 { execsql {SELECT * FROM sqlite_master} execsql BEGIN list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg -} {1 SQLITE_BUSY_SNAPSHOT} +} {1 SQLITE_ERROR_SNAPSHOT} do_test 2.3 { execsql COMMIT @@ -134,7 +134,7 @@ do_test 2.5 { sqlite3_snapshot_recover db main execsql BEGIN list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg -} {1 SQLITE_BUSY_SNAPSHOT} +} {1 SQLITE_ERROR_SNAPSHOT} #------------------------------------------------------------------------- # Check that calling sqlite3_snapshot_recover() does not confuse the @@ -197,4 +197,45 @@ do_test 4.7 { list [catch { sqlite3_snapshot_recover db aux } msg] $msg } {1 SQLITE_ERROR} +#------------------------------------------------------------------------- +reset_db +sqlite3 db2 test.db +do_execsql_test 5.0 { + CREATE TABLE t2(x); + PRAGMA journal_mode = wal; + INSERT INTO t2 VALUES('abc'); + INSERT INTO t2 VALUES('def'); + INSERT INTO t2 VALUES('ghi'); +} {wal} + +do_test 5.1 { + execsql { + SELECT * FROM t2; + BEGIN; + } db2 + set snap [sqlite3_snapshot_get_blob db2 main] + db2 eval END +} {} + +do_test 5.2 { + execsql BEGIN db2 + sqlite3_snapshot_open_blob db2 main $snap + db2 eval { SELECT * FROM t2 ; END } +} {abc def ghi} + +do_test 5.3 { + execsql { PRAGMA wal_checkpoint = RESTART } + execsql BEGIN db2 + sqlite3_snapshot_open_blob db2 main $snap + db2 eval { SELECT * FROM t2 ; END } +} {abc def ghi} + +do_test 5.4 { + execsql { INSERT INTO t2 VALUES('jkl') } + execsql BEGIN db2 + list [catch { sqlite3_snapshot_open_blob db2 main $snap } msg] $msg +} {1 SQLITE_ERROR_SNAPSHOT} + + finish_test + diff --git a/test/snapshot3.test b/test/snapshot3.test new file mode 100644 index 0000000000..8c330d7cbf --- /dev/null +++ b/test/snapshot3.test @@ -0,0 +1,100 @@ +# 2016 September 23 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The focus +# of this file is the sqlite3_snapshot_xxx() APIs. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !snapshot {finish_test; return} +set testprefix snapshot3 + +# This test does not work with the inmemory_journal permutation. The reason +# is that each connection opened as part of this permutation executes +# "PRAGMA journal_mode=memory", which fails if the database is in wal mode +# and there are one or more existing connections. +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + +#------------------------------------------------------------------------- +# This block of tests verifies that it is not possible to wrap the wal +# file - using a writer or a "PRAGMA wal_checkpoint = TRUNCATE" - while +# there is an open snapshot transaction (transaction opened using +# sqlite3_snapshot_open()). +# +do_execsql_test 1.0 { + CREATE TABLE t1(y); + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(3); + INSERT INTO t1 VALUES(4); +} {wal} + +do_test 1.1 { + sqlite3 db2 test.db + sqlite3 db3 test.db + + execsql {SELECT * FROM sqlite_master} db2 + execsql {SELECT * FROM sqlite_master} db3 + + db2 trans { set snap [sqlite3_snapshot_get_blob db2 main] } + db2 eval { SELECT * FROM t1 } +} {1 2 3 4} + +do_test 1.2 { + execsql BEGIN db2 + sqlite3_snapshot_open_blob db2 main $snap + db2 eval { SELECT * FROM t1 } +} {1 2 3 4} + +do_test 1.2 { + execsql END db2 + execsql { PRAGMA wal_checkpoint } + + execsql BEGIN db2 + sqlite3_snapshot_open_blob db2 main $snap + db2 eval { SELECT * FROM t1 } +} {1 2 3 4} + +set sz [file size test.db-wal] +do_test 1.3 { + execsql { PRAGMA wal_checkpoint = truncate } + file size test.db-wal +} $sz + +do_test 1.4 { + execsql BEGIN db3 + list [catch { sqlite3_snapshot_open_blob db3 main $snap } msg] $msg +} {0 {}} + +do_test 1.5 { + db3 eval { SELECT * FROM t1; END } +} {1 2 3 4} + +do_test 1.6 { + db2 eval { SELECT * FROM t1; END } +} {1 2 3 4} + +do_test 1.7 { + execsql { PRAGMA wal_checkpoint = truncate } + file size test.db-wal +} 0 + +do_test 1.8 { + execsql BEGIN db3 + list [catch { sqlite3_snapshot_open_blob db3 main $snap } msg] $msg +} {1 SQLITE_ERROR_SNAPSHOT} + +finish_test + diff --git a/test/snapshot4.test b/test/snapshot4.test new file mode 100644 index 0000000000..90a8d254e7 --- /dev/null +++ b/test/snapshot4.test @@ -0,0 +1,75 @@ +# 2018 August 28 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The focus +# of this file is the sqlite3_snapshot_xxx() APIs. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !snapshot {finish_test; return} +set testprefix snapshot4 + +# This test does not work with the inmemory_journal permutation. The reason +# is that each connection opened as part of this permutation executes +# "PRAGMA journal_mode=memory", which fails if the database is in wal mode +# and there are one or more existing connections. +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + +sqlite3 db2 test.db + +do_execsql_test 1.0 { + PRAGMA cache_size = 10; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, randomblob(400)); + PRAGMA journal_mode = wal; + WITH s(i) AS ( + SELECT 2 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO t1 SELECT i, randomblob(400) FROM s; +} {wal} + +do_test 1.1 { + execsql { + BEGIN; + SELECT count(*) FROM t1; + } +} {100} + +do_test 1.2 { + db2 eval { + SELECT count(*) FROM t1; + CREATE TABLE t2(x); + } +} {100} + +do_test 1.3 { + set ::snap [sqlite3_snapshot_get_blob db main] + db2 eval { PRAGMA wal_checkpoint } +} {0 54 52} + +do_test 1.4 { + execsql { + COMMIT; + SELECT * FROM sqlite_master; + BEGIN; + } + sqlite3_snapshot_open_blob db main $::snap + execsql { + SELECT count(*) FROM t1 + } +} {100} + + +finish_test + diff --git a/test/snapshot_fault.test b/test/snapshot_fault.test index 5c6cf40a6f..c0df4ec8e0 100644 --- a/test/snapshot_fault.test +++ b/test/snapshot_fault.test @@ -47,7 +47,7 @@ do_faultsim_test 1.0 -prep { } -test { db2 eval BEGIN if {[catch { sqlite3_snapshot_open db2 main $::snapshot } msg]} { - if {$msg != "SQLITE_BUSY_SNAPSHOT" && $msg != "SQLITE_BUSY"} { + if {$msg != "SQLITE_ERROR_SNAPSHOT" && $msg != "SQLITE_BUSY"} { error "error is $msg" } } else { @@ -98,7 +98,7 @@ do_faultsim_test 2.0 -prep { db eval BEGIN if {[catch { sqlite3_snapshot_open db main $::snapshot } msg]} { - if {$msg != "SQLITE_BUSY_SNAPSHOT" && $msg != "SQLITE_BUSY"} { + if {$msg != "SQLITE_ERROR_SNAPSHOT" && $msg != "SQLITE_BUSY"} { error "error is $msg" } } else { diff --git a/test/snapshot_up.test b/test/snapshot_up.test new file mode 100644 index 0000000000..651a92ac64 --- /dev/null +++ b/test/snapshot_up.test @@ -0,0 +1,184 @@ +# 2018 August 6 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Tests for calling sqlite3_snapshot_open() when there is already +# a read transaction open on the database. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !snapshot {finish_test; return} +set testprefix snapshot_up + +# This test does not work with the inmemory_journal permutation. The reason +# is that each connection opened as part of this permutation executes +# "PRAGMA journal_mode=memory", which fails if the database is in wal mode +# and there are one or more existing connections. +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); +} {wal} + +do_test 1.1 { + execsql BEGIN + set ::snap1 [sqlite3_snapshot_get db main] + execsql COMMIT + execsql { INSERT INTO t1 VALUES(10, 11, 12); } + execsql BEGIN + set ::snap2 [sqlite3_snapshot_get db main] + execsql COMMIT + execsql { INSERT INTO t1 VALUES(13, 14, 15); } + execsql BEGIN + set ::snap3 [sqlite3_snapshot_get db main] + execsql COMMIT +} {} + +do_execsql_test 1.2 { + BEGIN; + SELECT * FROM t1 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15} + +do_test 1.3 { + sqlite3_snapshot_open db main $::snap1 + execsql { SELECT * FROM t1 } +} {1 2 3 4 5 6 7 8 9} + +do_test 1.4 { + sqlite3_snapshot_open db main $::snap2 + execsql { SELECT * FROM t1 } +} {1 2 3 4 5 6 7 8 9 10 11 12} + +do_test 1.5 { + sqlite3 db2 test.db + execsql { PRAGMA wal_checkpoint } db2 +} {0 5 4} + +do_execsql_test 1.6 { + SELECT * FROM t1 +} {1 2 3 4 5 6 7 8 9 10 11 12} + +do_test 1.7 { + list [catch { sqlite3_snapshot_open db main $::snap1 } msg] $msg +} {1 SQLITE_ERROR_SNAPSHOT} + +do_execsql_test 1.8 { + SELECT * FROM t1 +} {1 2 3 4 5 6 7 8 9 10 11 12} + +do_test 1.9 { + execsql { COMMIT ; BEGIN } + list [catch { sqlite3_snapshot_open db main $::snap1 } msg] $msg +} {1 SQLITE_ERROR_SNAPSHOT} + +do_test 1.10 { + execsql { COMMIT } + execsql { + PRAGMA wal_checkpoint; + DELETE FROM t1 WHERE a = 1; + } db2 + execsql BEGIN + set ::snap4 [sqlite3_snapshot_get db main] + execsql COMMIT + execsql { + DELETE FROM t1 WHERE a = 4; + } db2 +} {} + +do_test 1.11 { + execsql { + BEGIN; + SELECT * FROM t1 + } +} {7 8 9 10 11 12 13 14 15} +do_test 1.12 { + sqlite3_snapshot_open db main $::snap4 + execsql { SELECT * FROM t1 } +} {4 5 6 7 8 9 10 11 12 13 14 15} + +do_test 1.13 { + list [catch { sqlite3_snapshot_open db main $::snap3 } msg] $msg +} {1 SQLITE_ERROR_SNAPSHOT} +do_test 1.14 { + execsql { SELECT * FROM t1 } +} {4 5 6 7 8 9 10 11 12 13 14 15} + +db close +db2 close +sqlite3 db test.db +do_execsql_test 1.15 { + BEGIN; + SELECT * FROM t1 +} {7 8 9 10 11 12 13 14 15} +do_test 1.16 { + list [catch { sqlite3_snapshot_open db main $::snap4 } msg] $msg +} {1 SQLITE_ERROR_SNAPSHOT} +do_execsql_test 1.17 { COMMIT } + +sqlite3_snapshot_free $::snap1 +sqlite3_snapshot_free $::snap2 +sqlite3_snapshot_free $::snap3 +sqlite3_snapshot_free $::snap4 + +#------------------------------------------------------------------------- +catch { db close } +sqlite3 db test.db +sqlite3 db2 test.db +sqlite3 db3 test.db + +proc xBusy {args} { return 1 } +db3 busy xBusy + +do_test 2.1 { + execsql { INSERT INTO t1 VALUES(16, 17, 18) } db2 + execsql BEGIN + set ::snap1 [sqlite3_snapshot_get db main] + execsql COMMIT + execsql { INSERT INTO t1 VALUES(19, 20, 21) } db2 + execsql BEGIN + set ::snap2 [sqlite3_snapshot_get db main] + execsql COMMIT + set {} {} +} {} + +do_execsql_test -db db2 2.2 { + BEGIN; + INSERT INTO t1 VALUES(19, 20, 21); +} + +do_test 2.3 { + execsql BEGIN + sqlite3_snapshot_open db main $::snap1 + execsql { SELECT * FROM t1 } +} {7 8 9 10 11 12 13 14 15 16 17 18} + +proc xBusy {args} { + set ::res [list [catch { sqlite3_snapshot_open db main $::snap2 } msg] $msg] + return 1 +} +db3 busy xBusy +do_test 2.4 { + execsql {PRAGMA wal_checkpoint = restart} db3 + set ::res +} {1 SQLITE_BUSY} + +sqlite3_snapshot_free $::snap1 +sqlite3_snapshot_free $::snap2 + +finish_test + diff --git a/test/soak.test b/test/soak.test index c457dec4a9..e8535a1456 100644 --- a/test/soak.test +++ b/test/soak.test @@ -67,12 +67,12 @@ set SOAKTESTS { set G(isquick) 1 -set soak_starttime [clock seconds] +set soak_starttime [clock_seconds] set soak_finishtime [expr {$soak_starttime + $TIMEOUT}] # Loop until the timeout is reached or an error occurs. # -for {set iRun 0} {[clock seconds] < $soak_finishtime} {incr iRun} { +for {set iRun 0} {[clock_seconds] < $soak_finishtime} {incr iRun} { set iIdx [expr {$iRun % [llength $SOAKTESTS]}] source [file join $testdir [lindex $SOAKTESTS $iIdx]] diff --git a/test/sort5.test b/test/sort5.test index 6ada81c9cc..80dce01ab6 100644 --- a/test/sort5.test +++ b/test/sort5.test @@ -73,6 +73,7 @@ catch { db close } forcedelete test.db sqlite3 db test.db -vfs tvfs execsql { CREATE TABLE t1(x) } +execsql { PRAGMA temp_store = 1 } # Each iteration of the following loop attempts to sort 10001 records # each a bit over 100 bytes in size. In total a little more than 1MiB @@ -88,6 +89,9 @@ foreach {tn pgsz cachesz bTemp} { 5 4096 -9000 0 6 1024 -9000 0 } { + if {$::TEMP_STORE>2} { + set bTemp 0 + } do_execsql_test 2.$tn.0 " PRAGMA page_size = $pgsz; VACUUM; diff --git a/test/sorterref.test b/test/sorterref.test new file mode 100644 index 0000000000..28445c6e72 --- /dev/null +++ b/test/sorterref.test @@ -0,0 +1,50 @@ +# 2018 April 14. +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix sorterref + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + ALTER TABLE t1 ADD COLUMN d DEFAULT 'string'; + INSERT INTO t1 VALUES(7, 8, 9, 'text'); +} + +do_execsql_test 1.1 { + SELECT * FROM t1 ORDER BY b; +} { + 1 2 3 string 4 5 6 string 7 8 9 text +} + +do_execsql_test 2.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a, b); + CREATE TABLE t2(c, d, PRIMARY KEY(c)) WITHOUT ROWID; + + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(2, 3); + INSERT INTO t1 VALUES(3, 4); + + INSERT INTO t2 VALUES(1, 'one'); + INSERT INTO t2 VALUES(3, 'three'); +} + +do_execsql_test 2.1 { + SELECT * FROM t1 LEFT JOIN t2 ON (a=c) ORDER BY b; +} {1 2 1 one 2 3 {} {} 3 4 3 three} + + + +finish_test diff --git a/test/speed4p.test b/test/speed4p.test index 024232e1b8..78ff9138db 100644 --- a/test/speed4p.test +++ b/test/speed4p.test @@ -168,7 +168,6 @@ speed_trial_tcl speed4p-subselect1 10000 stmt $script set script { db eval BEGIN for {set ii 1} {$ii < 10000} {incr ii} { - set v [expr {$ii*3}] db eval {UPDATE t1 SET i=i+1 WHERE rowid=$ii} } db eval COMMIT diff --git a/test/speedtest1.c b/test/speedtest1.c index db3a558a38..cf03c5354b 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -25,7 +25,6 @@ static const char zHelp[] = " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n" " --repeat N Repeat each SELECT N times (default: 1)\n" " --reprepare Reprepare each statement upon every invocation\n" - " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n" " --serialized Set serialized threading mode\n" " --singlethread Set single-threaded mode - disables all mutexing\n" " --sqlonly No-op. Only show the SQL that would have been run.\n" @@ -33,7 +32,7 @@ static const char zHelp[] = " --size N Relative test size. Default=100\n" " --stats Show statistics at the end\n" " --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n" - " --testset T Run test-set T (main, cte, rtree, orm, debug)\n" + " --testset T Run test-set T (main, cte, rtree, orm, fp, debug)\n" " --trace Turn on SQL tracing\n" " --threads N Use up to N threads for sorting\n" " --utf16be Set text encoding to UTF-16BE\n" @@ -1121,7 +1120,77 @@ void testset_cte(void){ ); speedtest1_run(); speedtest1_end_test(); +} +/* +** Compute a pseudo-random floating point ascii number. +*/ +void speedtest1_random_ascii_fp(char *zFP){ + int x = speedtest1_random(); + int y = speedtest1_random(); + int z; + z = y%10; + if( z<0 ) z = -z; + y /= 10; + sqlite3_snprintf(100,zFP,"%d.%de%d",y,z,x%200); +} + +/* +** A testset for floating-point numbers. +*/ +void testset_fp(void){ + int n; + int i; + char zFP1[100]; + char zFP2[100]; + + n = g.szTest*5000; + speedtest1_begin_test(100, "Fill a table with %d FP values", n*2); + speedtest1_exec("BEGIN"); + speedtest1_exec("CREATE%s TABLE t1(a REAL %s, b REAL %s);", + isTemp(1), g.zNN, g.zNN); + speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2); -- %d times", n); + for(i=1; i<=n; i++){ + speedtest1_random_ascii_fp(zFP1); + speedtest1_random_ascii_fp(zFP2); + sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC); + sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + n = g.szTest/25 + 2; + speedtest1_begin_test(110, "%d range queries", n); + speedtest1_prepare("SELECT sum(b) FROM t1 WHERE a BETWEEN ?1 AND ?2"); + for(i=1; i<=n; i++){ + speedtest1_random_ascii_fp(zFP1); + speedtest1_random_ascii_fp(zFP2); + sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC); + sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_end_test(); + + speedtest1_begin_test(120, "CREATE INDEX three times"); + speedtest1_exec("BEGIN;"); + speedtest1_exec("CREATE INDEX t1a ON t1(a);"); + speedtest1_exec("CREATE INDEX t1b ON t1(b);"); + speedtest1_exec("CREATE INDEX t1ab ON t1(a,b);"); + speedtest1_exec("COMMIT;"); + speedtest1_end_test(); + + n = g.szTest/3 + 2; + speedtest1_begin_test(130, "%d indexed range queries", n); + speedtest1_prepare("SELECT sum(b) FROM t1 WHERE a BETWEEN ?1 AND ?2"); + for(i=1; i<=n; i++){ + speedtest1_random_ascii_fp(zFP1); + speedtest1_random_ascii_fp(zFP2); + sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC); + sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_end_test(); } #ifdef SQLITE_ENABLE_RTREE @@ -1178,10 +1247,11 @@ void testset_rtree(int p1, int p2){ unsigned mxCoord; unsigned x0, x1, y0, y1, z0, z1; unsigned iStep; + unsigned mxRowid; int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*500 ); mxCoord = 15000; - n = g.szTest*500; + mxRowid = n = g.szTest*500; speedtest1_begin_test(100, "%d INSERTs into an r-tree", n); speedtest1_exec("BEGIN"); speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)"); @@ -1208,7 +1278,7 @@ void testset_rtree(int p1, int p2){ speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1"); speedtest1_end_test(); - n = g.szTest*100; + n = g.szTest*200; speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n); speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2"); iStep = mxCoord/n; @@ -1221,7 +1291,7 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); if( g.bVerify ){ - n = g.szTest*100; + n = g.szTest*200; speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries"); speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2"); iStep = mxCoord/n; @@ -1237,7 +1307,7 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); } - n = g.szTest*100; + n = g.szTest*200; speedtest1_begin_test(120, "%d one-dimensional overlap slice queries", n); speedtest1_prepare("SELECT count(*) FROM rt1 WHERE y1>=?1 AND y0<=?2"); iStep = mxCoord/n; @@ -1250,7 +1320,7 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); if( g.bVerify ){ - n = g.szTest*100; + n = g.szTest*200; speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries"); speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?2"); iStep = mxCoord/n; @@ -1267,7 +1337,7 @@ void testset_rtree(int p1, int p2){ } - n = g.szTest*100; + n = g.szTest*200; speedtest1_begin_test(125, "%d custom geometry callback queries", n); sqlite3_rtree_geometry_callback(g.db, "xslice", xsliceGeometryCallback, 0); speedtest1_prepare("SELECT count(*) FROM rt1 WHERE id MATCH xslice(?1,?2)"); @@ -1304,6 +1374,52 @@ void testset_rtree(int p1, int p2){ speedtest1_run(); } speedtest1_end_test(); + + n = g.szTest*50; + speedtest1_begin_test(150, "%d UPDATEs using rowid", n); + speedtest1_prepare("UPDATE rt1 SET x0=x0+100, x1=x1+100 WHERE id=?1"); + for(i=1; i<=n; i++){ + sqlite3_bind_int(g.pStmt, 1, (i*251)%mxRowid + 1); + speedtest1_run(); + } + speedtest1_end_test(); + + n = g.szTest*5; + speedtest1_begin_test(155, "%d UPDATEs using one-dimensional overlap", n); + speedtest1_prepare("UPDATE rt1 SET x0=x0-100, x1=x1-100" + " WHERE y1>=?1 AND y0<=?1+5"); + iStep = mxCoord/n; + for(i=0; i=?1 AND y0<=?1+5"); + iStep = mxCoord/n; + for(i=0; i=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); - nScratch = integerValue(argv[i+1]); - szScratch = integerValue(argv[i+2]); - i += 2; #if SQLITE_VERSION_NUMBER>=3006000 }else if( strcmp(z,"serialized")==0 ){ sqlite3_config(SQLITE_CONFIG_SERIALIZED); @@ -1816,13 +2131,6 @@ int main(int argc, char **argv){ rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); if( rc ) fatal_error("pcache configuration failed: %d\n", rc); } - if( nScratch>0 && szScratch>0 ){ - pScratch = malloc( nScratch*(sqlite3_int64)szScratch ); - if( pScratch==0 ) fatal_error("cannot allocate %lld-byte scratch\n", - nScratch*(sqlite3_int64)szScratch); - rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch); - if( rc ) fatal_error("scratch configuration failed: %d\n", rc); - } if( nLook>=0 ){ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); } @@ -1883,6 +2191,10 @@ int main(int argc, char **argv){ testset_orm(); }else if( strcmp(zTSet,"cte")==0 ){ testset_cte(); + }else if( strcmp(zTSet,"fp")==0 ){ + testset_fp(); + }else if( strcmp(zTSet,"trigger")==0 ){ + testset_trigger(); }else if( strcmp(zTSet,"rtree")==0 ){ #ifdef SQLITE_ENABLE_RTREE testset_rtree(6, 147); @@ -1891,11 +2203,16 @@ int main(int argc, char **argv){ "the R-Tree tests\n"); #endif }else{ - fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree\n", + fatal_error("unknown testset: \"%s\"\n" + "Choices: cte debug1 fp main orm rtree trigger\n", zTSet); } speedtest1_final(); + if( showStats ){ + sqlite3_exec(g.db, "PRAGMA compile_options", xCompileOptions, 0, 0); + } + /* Database connection statistics printed after both prepared statements ** have been finalized */ #if SQLITE_VERSION_NUMBER>=3007009 @@ -1939,14 +2256,10 @@ int main(int argc, char **argv){ #endif sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0); printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi); - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHi, 0); - printf("-- Scratch Overflow Bytes: %d (max %d)\n", iCur,iHi); sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0); printf("-- Largest Allocation: %d bytes\n",iHi); sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0); printf("-- Largest Pcache Allocation: %d bytes\n",iHi); - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0); - printf("-- Largest Scratch Allocation: %d bytes\n", iHi); } #endif @@ -1959,7 +2272,6 @@ int main(int argc, char **argv){ /* Release memory */ free( pLook ); free( pPCache ); - free( pScratch ); free( pHeap ); return 0; } diff --git a/test/spellfix.test b/test/spellfix.test index 8128bb59d2..68bcfd5adb 100644 --- a/test/spellfix.test +++ b/test/spellfix.test @@ -279,7 +279,7 @@ ifcapable trace { do_tracesql_test 6.2.3 { SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner'; } {keener 300 - {SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2=?1 AND k2=2} { set unlocked unknown } + proc int2str {i} { string range [string repeat "$i." 450] 0 899 } db func int2str int2str @@ -55,7 +58,7 @@ do_execsql_test 1.1 { COMMIT; PRAGMA lock_status; -} {main unlocked temp closed} +} [list main $unlocked temp closed] do_execsql_test 1.2 { UPDATE t1 SET b=int2str(2); diff --git a/test/temptable2.test b/test/temptable2.test index ffa69b6150..d940214495 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -344,7 +344,7 @@ do_execsql_test 10.1 { } ifcapable mmap { - if {[permutation]!="journaltest"} { + if {[permutation]!="journaltest" && $::TEMP_STORE<2} { # The journaltest permutation does not support mmap, so this part of # the test is omitted. do_execsql_test 10.2 { PRAGMA mmap_size = 512000 } 512000 diff --git a/test/tester.tcl b/test/tester.tcl index 38c19701c6..14808d9cd9 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -456,6 +456,11 @@ if {[info exists cmdlinearg]==0} { {^-+malloctrace=.+$} { foreach {dummy cmdlinearg(malloctrace)} [split $a =] break if {$cmdlinearg(malloctrace)} { + if {0==$::sqlite_options(memdebug)} { + set err "Error: --malloctrace=1 requires an SQLITE_MEMDEBUG build" + puts stderr $err + exit 1 + } sqlite3_memdebug_log start } } @@ -959,10 +964,83 @@ proc do_timed_execsql_test {testname sql {result {}}} { uplevel do_test [list $testname] [list "execsql_timed {$sql}"]\ [list [list {*}$result]] } -proc do_eqp_test {name sql res} { - uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res] + +# Run an EXPLAIN QUERY PLAN $sql in database "db". Then rewrite the output +# as an ASCII-art graph and return a string that is that graph. +# +# Hexadecimal literals in the output text are converted into "xxxxxx" since those +# literals are pointer values that might very from one run of the test to the +# next, yet we want the output to be consistent. +# +proc query_plan_graph {sql} { + db eval "EXPLAIN QUERY PLAN $sql" { + set dx($id) $detail + lappend cx($parent) $id + } + set a "\n QUERY PLAN\n" + append a [append_graph " " dx cx 0] + regsub -all { 0x[A-F0-9]+\y} $a { xxxxxx} a + regsub -all {(MATERIALIZE|CO-ROUTINE|SUBQUERY) \d+\y} $a {\1 xxxxxx} a + return $a } +# Helper routine for [query_plan_graph SQL]: +# +# Output rows of the graph that are children of $level. +# +# prefix: Prepend to every output line +# +# dxname: Name of an array variable that stores text describe +# The description for $id is $dx($id) +# +# cxname: Name of an array variable holding children of item. +# Children of $id are $cx($id) +# +# level: Render all lines that are children of $level +# +proc append_graph {prefix dxname cxname level} { + upvar $dxname dx $cxname cx + set a "" + set x $cx($level) + set n [llength $x] + for {set i 0} {$i<$n} {incr i} { + set id [lindex $x $i] + if {$i==$n-1} { + set p1 "`--" + set p2 " " + } else { + set p1 "|--" + set p2 "| " + } + append a $prefix$p1$dx($id)\n + if {[info exists cx($id)]} { + append a [append_graph "$prefix$p2" dx cx $id] + } + } + return $a +} + +# Do an EXPLAIN QUERY PLAN test on input $sql with expected results $res +# +# If $res begins with a "\s+QUERY PLAN\n" then it is assumed to be the +# complete graph which must match the output of [query_plan_graph $sql] +# exactly. +# +# If $res does not begin with "\s+QUERY PLAN\n" then take it is a string +# that must be found somewhere in the query plan output. +# +proc do_eqp_test {name sql res} { + if {[regexp {^\s+QUERY PLAN\n} $res]} { + uplevel do_test $name [list [list query_plan_graph $sql]] [list $res] + } else { + if {[string index $res 0]!="/"} { + set res "/*$res*/" + } + uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res] + } +} + + #------------------------------------------------------------------------- # Usage: do_select_tests PREFIX ?SWITCHES? TESTLIST # @@ -1185,13 +1263,13 @@ proc finalize_testing {} { output2 "Unfreed memory: [sqlite3_memory_used] bytes in\ [lindex [sqlite3_status SQLITE_STATUS_MALLOC_COUNT 0] 1] allocations" incr nErr - ifcapable memdebug||mem5||(mem3&&debug) { + ifcapable mem5||(mem3&&debug) { output2 "Writing unfreed memory log to \"./memleak.txt\"" sqlite3_memdebug_dump ./memleak.txt } } else { output2 "All memory allocations freed - no leaks" - ifcapable memdebug||mem5 { + ifcapable mem5 { sqlite3_memdebug_dump ./memusage.txt } } @@ -1202,15 +1280,14 @@ proc finalize_testing {} { output2 "Number of malloc() : [sqlite3_memdebug_malloc_count] calls" } if {$::cmdlinearg(malloctrace)} { - output2 "Writing mallocs.sql..." - memdebug_log_sql + output2 "Writing mallocs.tcl..." + memdebug_log_sql mallocs.tcl sqlite3_memdebug_log stop sqlite3_memdebug_log clear - if {[sqlite3_memory_used]>0} { - output2 "Writing leaks.sql..." + output2 "Writing leaks.tcl..." sqlite3_memdebug_log sync - memdebug_log_sql leaks.sql + memdebug_log_sql leaks.tcl } } foreach f [glob -nocomplain test.db-*-journal] { @@ -1241,14 +1318,6 @@ proc show_memstats {} { set x [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] set val [format {now %10d max %10d} [lindex $x 1] [lindex $x 2]] output1 "Page-cache overflow: $val" - set x [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] - set val [format {now %10d max %10d} [lindex $x 1] [lindex $x 2]] - output1 "Scratch memory used: $val" - set x [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] - set y [sqlite3_status SQLITE_STATUS_SCRATCH_SIZE 0] - set val [format {now %10d max %10d max-size %10d} \ - [lindex $x 1] [lindex $x 2] [lindex $y 2]] - output1 "Scratch overflow: $val" ifcapable yytrackmaxstackdepth { set x [sqlite3_status SQLITE_STATUS_PARSER_STACK 0] set val [format { max %10d} [lindex $x 2]] @@ -1954,7 +2023,7 @@ proc dbcksum {db dbname} { return [md5 $txt] } -proc memdebug_log_sql {{filename mallocs.sql}} { +proc memdebug_log_sql {filename} { set data [sqlite3_memdebug_log dump] set nFrame [expr [llength [lindex $data 0]]-2] @@ -2000,8 +2069,18 @@ proc memdebug_log_sql {{filename mallocs.sql}} { append sql "INSERT INTO ${database}.file VALUES('$f', '$contents');\n" } + set escaped "BEGIN; ${tbl}${tbl2}${tbl3}${sql} ; COMMIT;" + set escaped [string map [list "{" "\\{" "}" "\\}"] $escaped] + set fd [open $filename w] - puts $fd "BEGIN; ${tbl}${tbl2}${tbl3}${sql} ; COMMIT;" + puts $fd "set BUILTIN {" + puts $fd $escaped + puts $fd "}" + puts $fd {set BUILTIN [string map [list "\\{" "{" "\\}" "}"] $BUILTIN]} + set mtv [open $::testdir/malloctraceviewer.tcl] + set txt [read $mtv] + close $mtv + puts $fd $txt close $fd } @@ -2279,13 +2358,17 @@ proc test_restore_config_pagecache {} { sqlite3 db test.db } -proc test_find_binary {nm} { +proc test_binary_name {nm} { if {$::tcl_platform(platform)=="windows"} { set ret "$nm.exe" } else { set ret $nm } - set ret [file normalize [file join $::cmdlinearg(TESTFIXTURE_HOME) $ret]] + file normalize [file join $::cmdlinearg(TESTFIXTURE_HOME) $ret] +} + +proc test_find_binary {nm} { + set ret [test_binary_name $nm] if {![file executable $ret]} { finish_test return "" @@ -2313,6 +2396,16 @@ proc test_find_sqldiff {} { return $prog } +# Call sqlite3_expanded_sql() on all statements associated with database +# connection $db. This sometimes finds use-after-free bugs if run with +# valgrind or address-sanitizer. +proc expand_all_sql {db} { + set stmt "" + while {[set stmt [sqlite3_next_stmt $db $stmt]]!=""} { + sqlite3_expanded_sql $stmt + } +} + # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. diff --git a/test/thread001.test b/test/thread001.test index a796c57b4a..7f21fb0738 100644 --- a/test/thread001.test +++ b/test/thread001.test @@ -141,5 +141,6 @@ foreach {tn same_db shared_cache} [list \ } sqlite3_enable_shared_cache $::enable_shared_cache +catch { db close } set sqlite_open_file_count 0 finish_test diff --git a/test/tkt-26ff0c2d1e.test b/test/tkt-26ff0c2d1e.test index 83a4f3d674..d7c5c6bae3 100644 --- a/test/tkt-26ff0c2d1e.test +++ b/test/tkt-26ff0c2d1e.test @@ -31,3 +31,5 @@ do_test bug-20100512-3 { sqlite3_column_int $STMT 0 } {555} sqlite3_finalize $STMT + +finish_test diff --git a/test/tkt-385a5b56b9.test b/test/tkt-385a5b56b9.test index 1338435ed6..22a9b38daf 100644 --- a/test/tkt-385a5b56b9.test +++ b/test/tkt-385a5b56b9.test @@ -34,20 +34,17 @@ do_execsql_test 2.0 { CREATE UNIQUE INDEX t2y ON t2(y); } -do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2x} -} +do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } \ + {SCAN TABLE t2 USING COVERING INDEX t2x} -do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } { - 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2y} -} +do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } \ + {SCAN TABLE t2 USING COVERING INDEX t2y} -do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } { - 0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)} -} +do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } \ + {SEARCH TABLE t2 USING INDEX t2y (y=?)} + +do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } \ + {SEARCH TABLE t2 USING INDEX t2x (x=?)} -do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } { - 0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x=?)} -} finish_test diff --git a/test/tkt-78e04e52ea.test b/test/tkt-78e04e52ea.test index 963ecf18d1..47a1093dd8 100644 --- a/test/tkt-78e04e52ea.test +++ b/test/tkt-78e04e52ea.test @@ -41,10 +41,8 @@ do_test tkt-78e04-1.3 { } } {} do_test tkt-78e04-1.4 { - execsql { - EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%'; - } -} {0 0 0 {SCAN TABLE USING COVERING INDEX i1}} + db eval {EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';} +} {/*SCAN TABLE USING COVERING INDEX i1*/} do_test tkt-78e04-1.5 { execsql { DROP TABLE ""; @@ -57,12 +55,12 @@ do_test tkt-78e04-2.1 { CREATE INDEX "" ON t2(x); EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=5; } -} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX (x=?)}} +} {/*SEARCH TABLE t2 USING COVERING INDEX (x=?)*/} do_test tkt-78e04-2.2 { execsql { DROP INDEX ""; EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=2; } -} {0 0 0 {SCAN TABLE t2}} +} {/*SCAN TABLE t2*/} finish_test diff --git a/test/tkt-7a31705a7e6.test b/test/tkt-7a31705a7e6.test index e3e402917d..fd862484ea 100644 --- a/test/tkt-7a31705a7e6.test +++ b/test/tkt-7a31705a7e6.test @@ -23,3 +23,5 @@ do_execsql_test tkt-7a31705a7e6-1.1 { CREATE TABLE t2x (b INTEGER PRIMARY KEY); SELECT t1.a FROM ((t1 JOIN t2 ON t1.a=t2.a) AS x JOIN t2x ON x.b=t2x.b) as y; } {} + +finish_test diff --git a/test/tkt-a8a0d2996a.test b/test/tkt-a8a0d2996a.test index 6b15e410e7..03c2ee9448 100644 --- a/test/tkt-a8a0d2996a.test +++ b/test/tkt-a8a0d2996a.test @@ -91,3 +91,5 @@ do_execsql_test 4.5 { do_execsql_test 4.6 { SELECT '1234x'/'10y'; } {123.4} + +finish_test diff --git a/test/tkt-b75a9ca6b0.test b/test/tkt-b75a9ca6b0.test index 0c81a534da..8fceb436c2 100644 --- a/test/tkt-b75a9ca6b0.test +++ b/test/tkt-b75a9ca6b0.test @@ -32,41 +32,41 @@ do_execsql_test 1.1 { CREATE INDEX i1 ON t1(x, y); } -set idxscan {0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}} -set tblscan {0 0 0 {SCAN TABLE t1}} -set grpsort {0 0 0 {USE TEMP B-TREE FOR GROUP BY}} -set sort {0 0 0 {USE TEMP B-TREE FOR ORDER BY}} +set idxscan {SCAN TABLE t1 USING COVERING INDEX i1} +set tblscan {SCAN TABLE t1} +set grpsort {USE TEMP B-TREE FOR GROUP BY} +set sort {USE TEMP B-TREE FOR ORDER BY} foreach {tn q res eqp} [subst -nocommands { 1 "SELECT * FROM t1 GROUP BY x, y ORDER BY x,y" {1 3 2 2 3 1} {$idxscan} 2 "SELECT * FROM t1 GROUP BY x, y ORDER BY x" - {1 3 2 2 3 1} {$idxscan $sort} + {1 3 2 2 3 1} {$idxscan*$sort} 3 "SELECT * FROM t1 GROUP BY y, x ORDER BY y, x" - {3 1 2 2 1 3} {$idxscan $sort} + {3 1 2 2 1 3} {$idxscan*$sort} 4 "SELECT * FROM t1 GROUP BY x ORDER BY x" {1 3 2 2 3 1} {$idxscan} 5 "SELECT * FROM t1 GROUP BY y ORDER BY y" - {3 1 2 2 1 3} {$tblscan $grpsort} + {3 1 2 2 1 3} {$tblscan*$grpsort} 6 "SELECT * FROM t1 GROUP BY y ORDER BY x" - {1 3 2 2 3 1} {$tblscan $grpsort $sort} + {1 3 2 2 3 1} {$tblscan*$grpsort*$sort} 7 "SELECT * FROM t1 GROUP BY x, y ORDER BY x, y DESC" - {1 3 2 2 3 1} {$idxscan $sort} + {1 3 2 2 3 1} {$idxscan*$sort} 8 "SELECT * FROM t1 GROUP BY x, y ORDER BY x DESC, y DESC" - {3 1 2 2 1 3} {$idxscan $sort} + {3 1 2 2 1 3} {$idxscan*$sort} 9 "SELECT * FROM t1 GROUP BY x, y ORDER BY x ASC, y ASC" {1 3 2 2 3 1} {$idxscan} 10 "SELECT * FROM t1 GROUP BY x, y ORDER BY x COLLATE nocase, y" - {1 3 2 2 3 1} {$idxscan $sort} + {1 3 2 2 3 1} {$idxscan*$sort} }] { do_execsql_test 1.$tn.1 $q $res diff --git a/test/tkt-c694113d5.test b/test/tkt-c694113d5.test new file mode 100644 index 0000000000..bac91fc900 --- /dev/null +++ b/test/tkt-c694113d5.test @@ -0,0 +1,36 @@ +# 2018-07-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. Specifically, +# it tests that ticket [c694113e50321afdf952e2d1235b08ba663f8399]: +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test tkt-c694113d5.100 { + sqlite3 db :memory: + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY); + CREATE TABLE t2(d INTEGER PRIMARY KEY,e,f); + INSERT INTO t1(a) VALUES(1),(2),(3),(4); + } + set answer {} + db eval {SELECT a FROM t1 WHERE NOT EXISTS(SELECT 1 FROM t2 WHERE d=a)} { + if {$a==3} { + lappend answer "CREATE INDEX" + db eval {CREATE INDEX t2e ON t2(e);} + } + lappend answer "a=$a" + } + set answer +} {a=1 a=2 {CREATE INDEX} a=3 a=4} + +finish_test diff --git a/test/tkt3334.test b/test/tkt3334.test index 5473ab4cf8..3527932de3 100644 --- a/test/tkt3334.test +++ b/test/tkt3334.test @@ -82,3 +82,5 @@ do_test tkt3334-1.10 { SELECT count(*) FROM (SELECT a FROM t1) WHERE a=1; } } {3} + +finish_test diff --git a/test/tkt3442.test b/test/tkt3442.test index ee9169ce2c..98a5e371c1 100644 --- a/test/tkt3442.test +++ b/test/tkt3442.test @@ -34,35 +34,24 @@ do_test tkt3442-1.1 { } } {} - -# Explain Query Plan -# -proc EQP {sql} { - uplevel "execsql {EXPLAIN QUERY PLAN $sql}" -} - - # These tests perform an EXPLAIN QUERY PLAN on both versions of the # SELECT referenced in ticket #3442 (both '5000' and "5000") # and verify that the query plan is the same. # -ifcapable explain { - do_test tkt3442-1.2 { - EQP { SELECT node FROM listhash WHERE id='5000' LIMIT 1; } - } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}} - do_test tkt3442-1.3 { - EQP { SELECT node FROM listhash WHERE id="5000" LIMIT 1; } - } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}} -} +do_eqp_test tkt3442-1.2 { + SELECT node FROM listhash WHERE id='5000' LIMIT 1; +} {SEARCH TABLE listhash USING INDEX ididx (id=?)} +do_eqp_test tkt3442-1.3 { + SELECT node FROM listhash WHERE id="5000" LIMIT 1; +} {SEARCH TABLE listhash USING INDEX ididx (id=?)} # Some extra tests testing other permutations of 5000. # -ifcapable explain { - do_test tkt3442-1.4 { - EQP { SELECT node FROM listhash WHERE id=5000 LIMIT 1; } - } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}} -} +do_eqp_test tkt3442-1.4 { + SELECT node FROM listhash WHERE id=5000 LIMIT 1; +} {SEARCH TABLE listhash USING INDEX ididx (id=?)} + do_test tkt3442-1.5 { catchsql { SELECT node FROM listhash WHERE id=[5000] LIMIT 1; diff --git a/test/tkt3457.test b/test/tkt3457.test index 0475741322..24b4f0eac0 100644 --- a/test/tkt3457.test +++ b/test/tkt3457.test @@ -19,6 +19,10 @@ if {$tcl_platform(platform) != "unix"} { finish_test return } +if {[atomic_batch_write test.db]} { + finish_test + return +} #----------------------------------------------------------------------- # To roll back a hot-journal file, the application needs read and write diff --git a/test/tpch01.test b/test/tpch01.test index ce48f8ec23..0e51b82b08 100644 --- a/test/tpch01.test +++ b/test/tpch01.test @@ -165,7 +165,7 @@ do_test tpch01-1.1 { order by o_year;}] set ::eqpres -} {/0 0 0 {SEARCH TABLE part USING INDEX bootleg_pti .P_TYPE=..} 0 1 2 {SEARCH TABLE lineitem USING INDEX lpki2 .L_PARTKEY=..}.*/} +} {/*SEARCH TABLE part USING INDEX bootleg_pti *SEARCH TABLE lineitem USING INDEX lpki2*/} do_test tpch01-1.1b { set ::eqpres } {/.* customer .* nation AS n1 .*/} @@ -187,6 +187,14 @@ group by c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment order by revenue desc; -} {0 0 1 {SEARCH TABLE orders USING INDEX odi (O_ORDERDATE>? AND O_ORDERDATE? AND O_ORDERDATE= 0 && $ns <= 9999999}]; # less than 0.010 seconds +} {/^-?\d+ 1$/} +do_test trace3-4.4 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record 2 + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set stmt [lindex [lindex $::stmtlist(record) 0] 0] + set ns [lindex [lindex $::stmtlist(record) 0] 1] + list $stmt [expr {$ns >= 0 && $ns <= 9999999}]; # less than 0.010 seconds +} {/^-?\d+ 1$/} + do_test trace3-5.1 { set ::stmtlist(record) {} db trace_v2 trace_v2_record row diff --git a/test/trigger1.test b/test/trigger1.test index a190efd464..8946cd85c9 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -728,4 +728,44 @@ do_execsql_test trigger1-17.0 { PRAGMA integrity_check; } {ok} +# 2018-04-26 +# When a BEFORE UPDATE trigger changes a column value in a row being +# updated, and that column value is used by the UPDATE to change other +# column, the value used to compute the update is from before the trigger. +# In the example that follows, the value of "b" in "c=b" is 2 (the value +# prior to running the BEFORE UPDATE trigger) not 1000. +# +do_execsql_test trigger1-18.0 { + CREATE TABLE t18(a PRIMARY KEY,b,c); + INSERT INTO t18(a,b,c) VALUES(1,2,3); + CREATE TRIGGER t18r1 BEFORE UPDATE ON t18 BEGIN + UPDATE t18 SET b=1000 WHERE a=old.a; + END; + UPDATE t18 SET c=b WHERE a=1; + SELECT * FROM t18; +} {1 1000 2} ;# Not: 1 1000 1000 +do_execsql_test trigger1-18.1 { + DELETE FROM t18; + INSERT INTO t18(a,b,c) VALUES(1,2,3); + UPDATE t18 SET c=b, b=b+1 WHERE a=1; + SELECT * FROM t18; +} {1 3 2} ;# Not: 1 1001 1000 + +# 2018-04-26 ticket [https://www.sqlite.org/src/tktview/d85fffd6ffe856092e] +# VDBE Program uses an expired value. +# +do_execsql_test trigger1-19.0 { + CREATE TABLE t19(a INT PRIMARY KEY, b, c)WITHOUT ROWID; + INSERT INTO t19(a,b,c) VALUES(1,2,3); + CREATE TRIGGER t19r3 BEFORE UPDATE ON t19 BEGIN SELECT new.b; END; + UPDATE t19 SET c=b WHERE a=1; + SELECT * FROM t19; +} {1 2 2} +do_execsql_test trigger1-19.1 { + DELETE FROM t19; + INSERT INTO t19(a,b,c) VALUES(1,2,3); + UPDATE t19 SET c=CASE WHEN b=2 THEN b ELSE b+99 END WHERE a=1; + SELECT * FROM t19; +} {1 2 2} + finish_test diff --git a/test/trigger7.test b/test/trigger7.test index 847d78cd7a..5fa7638f8e 100644 --- a/test/trigger7.test +++ b/test/trigger7.test @@ -113,6 +113,6 @@ do_test trigger7-99.1 { db close catch { sqlite3 db test.db } catchsql { DROP TRIGGER t2r5 } -} {1 {malformed database schema (t2r12)}} +} {/1 {malformed database schema .*}/} finish_test diff --git a/test/triggerA.test b/test/triggerA.test index 821e2d90e4..598d291295 100644 --- a/test/triggerA.test +++ b/test/triggerA.test @@ -200,13 +200,6 @@ do_test triggerA-2.11 { } } {3 305 3 9900305 4 404 4 9900404 5 504 5 9900504} -# Only run the reamining tests if memory debugging is turned on. -# -ifcapable !memdebug { - puts "Skipping triggerA malloc tests: not compiled with -DSQLITE_MEMDEBUG..." - finish_test - return -} source $testdir/malloc_common.tcl # Save a copy of the current database configuration. diff --git a/test/triggerE.test b/test/triggerE.test index a82ac9d2a5..8b010fa176 100644 --- a/test/triggerE.test +++ b/test/triggerE.test @@ -57,6 +57,7 @@ foreach {tn defn} { 7 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 ORDER BY ?; END; } 8 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = ?; END; } 9 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = 1 WHERE d = ?; END; } + 10 { AFTER INSERT ON t1 BEGIN SELECT * FROM pragma_stats(?); END; } } { catchsql {drop trigger tr1} do_catchsql_test 1.1.$tn "CREATE TRIGGER tr1 $defn" [list 1 $errmsg] diff --git a/test/triggerG.test b/test/triggerG.test index c770b5bd76..f5965e1707 100644 --- a/test/triggerG.test +++ b/test/triggerG.test @@ -62,4 +62,17 @@ do_execsql_test 200 { SELECT b FROM t2 ORDER BY b; } {20202 20203 20302 20303 30202 30203 30302 30303 40202 40203 40302 40303 50202 50203 50302 50303} +# At one point the following was causing an assert() to fail. +# +do_execsql_test 300 { + CREATE TABLE t4(x); + CREATE TRIGGER tr4 AFTER INSERT ON t4 BEGIN + SELECT 0x2147483648e0e0099 AS y WHERE y; + END; +} + +do_catchsql_test 310 { + INSERT INTO t4 VALUES(1); +} {1 {hex literal too big: 0x2147483648e0e0099}} + finish_test diff --git a/test/unordered.test b/test/unordered.test index 147e91f0d9..cdbbabeb3a 100644 --- a/test/unordered.test +++ b/test/unordered.test @@ -40,28 +40,27 @@ foreach idxmode {ordered unordered} { sqlite3 db test.db foreach {tn sql r(ordered) r(unordered)} { 1 "SELECT * FROM t1 ORDER BY a" - {0 0 0 {SCAN TABLE t1 USING INDEX i1}} - {0 0 0 {SCAN TABLE t1} 0 0 0 {USE TEMP B-TREE FOR ORDER BY}} + {SCAN TABLE t1 USING INDEX i1} + {SCAN TABLE t1*USE TEMP B-TREE FOR ORDER BY} 2 "SELECT * FROM t1 WHERE a > 100" - {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}} - {0 0 0 {SCAN TABLE t1}} + {SEARCH TABLE t1 USING INDEX i1 (a>?)} + {SCAN TABLE t1} 3 "SELECT * FROM t1 WHERE a = ? ORDER BY rowid" - {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} - {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY}} + {SEARCH TABLE t1 USING INDEX i1 (a=?)} + {SEARCH TABLE t1 USING INDEX i1 (a=?)*USE TEMP B-TREE FOR ORDER BY} 4 "SELECT max(a) FROM t1" - {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1}} - {0 0 0 {SEARCH TABLE t1}} + {SEARCH TABLE t1 USING COVERING INDEX i1} + {SEARCH TABLE t1} 5 "SELECT group_concat(b) FROM t1 GROUP BY a" - {0 0 0 {SCAN TABLE t1 USING INDEX i1}} - {0 0 0 {SCAN TABLE t1} 0 0 0 {USE TEMP B-TREE FOR GROUP BY}} + {SCAN TABLE t1 USING INDEX i1} + {SCAN TABLE t1*USE TEMP B-TREE FOR GROUP BY} 6 "SELECT * FROM t1 WHERE a = ?" - {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} - {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} + {SEARCH TABLE t1 USING INDEX i1 (a=?)} + {SEARCH TABLE t1 USING INDEX i1 (a=?)} 7 "SELECT count(*) FROM t1" - {0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}} - {0 0 0 {SCAN TABLE t1}} + {SCAN TABLE t1 USING COVERING INDEX i1} + {SCAN TABLE t1} } { do_eqp_test 1.$idxmode.$tn $sql $r($idxmode) } diff --git a/test/update.test b/test/update.test index d7baf6e702..99fff45818 100644 --- a/test/update.test +++ b/test/update.test @@ -508,6 +508,18 @@ ifcapable subquery { SELECT a,e FROM t1; } } {1 15 2 8} + do_test update-11.3 { + execsql { + UPDATE t1 AS xyz SET e=e+1 WHERE xyz.a IN (SELECT a FROM t1); + SELECT a,e FROM t1; + } + } {1 16 2 9} + do_test update-11.4 { + execsql { + UPDATE t1 AS xyz SET e=e+1 WHERE EXISTS(SELECT 1 FROM t1 WHERE t1.a0 OR b>0; +} + +do_execsql_test 6.2 { + SELECT * FROM d1; +} {3 2} finish_test diff --git a/test/upsert1.test b/test/upsert1.test new file mode 100644 index 0000000000..0d13cd8543 --- /dev/null +++ b/test/upsert1.test @@ -0,0 +1,214 @@ +# 2018-04-12 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases for UPSERT + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix zipfile + +do_execsql_test upsert1-100 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c DEFAULT 0); + CREATE UNIQUE INDEX t1x1 ON t1(b); + INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT DO NOTHING; + INSERT INTO t1(a,b) VALUES(1,99),(99,2) ON CONFLICT DO NOTHING; + SELECT * FROM t1; +} {1 2 0} +do_execsql_test upsert1-101 { + DELETE FROM t1; + INSERT INTO t1(a,b) VALUES(2,3) ON CONFLICT(a) DO NOTHING; + INSERT INTO t1(a,b) VALUES(2,99) ON CONFLICT(a) DO NOTHING; + SELECT * FROM t1; +} {2 3 0} +do_execsql_test upsert1-102 { + DELETE FROM t1; + INSERT INTO t1(a,b) VALUES(3,4) ON CONFLICT(b) DO NOTHING; + INSERT INTO t1(a,b) VALUES(99,4) ON CONFLICT(b) DO NOTHING; + SELECT * FROM t1; +} {3 4 0} +do_catchsql_test upsert1-110 { + INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(x) DO NOTHING; + SELECT * FROM t1; +} {1 {no such column: x}} +do_catchsql_test upsert1-120 { + INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(c) DO NOTHING; + SELECT * FROM t1; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} +breakpoint +do_catchsql_test upsert1-130 { + INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(b COLLATE nocase) DO NOTHING; + SELECT * FROM t1; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} +do_execsql_test upsert1-140 { + DELETE FROM t1; + INSERT INTO t1(a,b) VALUES(5,6) ON CONFLICT(b COLLATE binary) DO NOTHING; + SELECT * FROM t1; +} {5 6 0} + +do_catchsql_test upsert1-200 { + DROP TABLE t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c DEFAULT 0); + CREATE UNIQUE INDEX t1x1 ON t1(a+b); + INSERT INTO t1(a,b) VALUES(7,8) ON CONFLICT(a+b) DO NOTHING; + INSERT INTO t1(a,b) VALUES(8,7),(9,6) ON CONFLICT(a+b) DO NOTHING; + SELECT * FROM t1; +} {0 {7 8 0}} +do_catchsql_test upsert1-201 { + INSERT INTO t1(a,b) VALUES(8,7),(9,6) ON CONFLICT(a) DO NOTHING; +} {1 {UNIQUE constraint failed: index 't1x1'}} +do_catchsql_test upsert1-210 { + DELETE FROM t1; + INSERT INTO t1(a,b) VALUES(9,10) ON CONFLICT(a+(+b)) DO NOTHING; + SELECT * FROM t1; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} + +do_catchsql_test upsert1-300 { + DROP INDEX t1x1; + DELETE FROM t1; + CREATE UNIQUE INDEX t1x1 ON t1(b) WHERE b>10; + INSERT INTO t1(a,b) VALUES(1,2),(3,2) ON CONFLICT(b) DO NOTHING; + SELECT * FROM t1; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} +do_catchsql_test upsert1-310 { + DELETE FROM t1; + INSERT INTO t1(a,b) VALUES(1,2),(3,2) ON CONFLICT(b) WHERE b!=10 DO NOTHING; + SELECT * FROM t1; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} +do_execsql_test upsert1-320 { + DELETE FROM t1; + INSERT INTO t1(a,b) VALUES(1,2),(3,2),(4,20),(5,20) + ON CONFLICT(b) WHERE b>10 DO NOTHING; + SELECT *, 'x' FROM t1 ORDER BY b, a; +} {1 2 0 x 3 2 0 x 4 20 0 x} + +# Upsert works with count_changes=on; +do_execsql_test upsert1-400 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a TEXT UNIQUE, b INT DEFAULT 1); + INSERT INTO t2(a) VALUES('one'),('two'),('three'); + PRAGMA count_changes=ON; + INSERT INTO t2(a) VALUES('one'),('one'),('three'),('four') + ON CONFLICT(a) DO UPDATE SET b=b+1; +} {1} +do_execsql_test upsert1-410 { + PRAGMA count_changes=OFF; + SELECT a, b FROM t2 ORDER BY a; +} {four 1 one 3 three 2 two 1} + +# Problem found by AFL prior to any release +do_execsql_test upsert1-500 { + DROP TABLE t1; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y INT UNIQUE); + INSERT INTO t1(x,y) SELECT 1,2 WHERE true + ON CONFLICT(x) DO UPDATE SET y=max(t1.y,excluded.y) AND true; + SELECT * FROM t1; +} {1 2} + +# 2018-07-11 +# Ticket https://sqlite.org/src/tktview/79cad5e4b2e219dd197242e9e5f4 +# UPSERT leads to a corrupt index. +# +do_execsql_test upsert1-600 { + DROP TABLE t1; + CREATE TABLE t1(b UNIQUE, a INT PRIMARY KEY) WITHOUT ROWID; + INSERT OR IGNORE INTO t1(a) VALUES('1') ON CONFLICT(a) DO NOTHING; + PRAGMA integrity_check; +} {ok} +do_execsql_test upsert1-610 { + DELETE FROM t1; + INSERT OR IGNORE INTO t1(a) VALUES('1'),(1) ON CONFLICT(a) DO NOTHING; + PRAGMA integrity_check; +} {ok} + +# 2018-08-14 +# Ticket https://www.sqlite.org/src/info/908f001483982c43 +# If there are multiple uniqueness contraints, the UPSERT should fire +# if the one constraint it targets fails, regardless of whether or not +# the other constraints pass or fail. In other words, the UPSERT constraint +# should be tested first. +# +do_execsql_test upsert1-700 { + DROP TABLE t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT, d INT, e INT); + CREATE UNIQUE INDEX t1b ON t1(b); + CREATE UNIQUE INDEX t1e ON t1(e); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(e) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-710 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(a) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-720 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(b) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-730 { + DROP TABLE t1; + CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT); + CREATE UNIQUE INDEX t1a ON t1(a); + CREATE UNIQUE INDEX t1b ON t1(b); + CREATE UNIQUE INDEX t1e ON t1(e); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(e) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-740 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(a) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-750 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(b) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-760 { + DROP TABLE t1; + CREATE TABLE t1(a INT PRIMARY KEY, b INT, c INT, d INT, e INT) WITHOUT ROWID; + CREATE UNIQUE INDEX t1a ON t1(a); + CREATE UNIQUE INDEX t1b ON t1(b); + CREATE UNIQUE INDEX t1e ON t1(e); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(e) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-770 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(a) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} +do_execsql_test upsert1-780 { + DELETE FROM t1; + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); + INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) + ON CONFLICT(b) DO UPDATE SET c=excluded.c; + SELECT * FROM t1; +} {1 2 33 4 5} + + +finish_test diff --git a/test/upsert2.test b/test/upsert2.test new file mode 100644 index 0000000000..1aa499e606 --- /dev/null +++ b/test/upsert2.test @@ -0,0 +1,170 @@ +# 2018-04-17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases for UPSERT + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix zipfile + +do_execsql_test upsert2-100 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b int, c DEFAULT 0); + INSERT INTO t1(a,b) VALUES(1,2),(3,4); + INSERT INTO t1(a,b) VALUES(1,8),(2,11),(3,1) + ON CONFLICT(a) DO UPDATE SET b=excluded.b, c=c+1 WHERE t1.b0; + CREATE UNIQUE INDEX abc2 ON abc(y) WHERE x='xyz' COLLATE nocase; + } +} { + reset_db + execsql $sql + do_execsql_test 4.$tn.1 { + INSERT INTO abc VALUES(1, 'one', 1); + INSERT INTO abc VALUES(2, 'two', 2); + INSERT INTO abc VALUES(3, 'xyz', 3); + INSERT INTO abc VALUES(4, 'XYZ', 4); + } + + foreach {tn2 oc res} { + 1 "ON CONFLICT DO NOTHING" 0 + 2 "ON CONFLICT(x) WHERE y>0 DO NOTHING" 0 + 3 "ON CONFLICT(x) DO NOTHING" 2 + 4 "ON CONFLICT(x) WHERE y>=0 DO NOTHING" 2 + 5 "ON CONFLICT(y) WHERE x='xyz' COLLATE nocase DO NOTHING" 1 + } { + do_catchsql_test 4.$tn.2.$tn2 " + INSERT INTO abc VALUES(5, 'one', 10) $oc + " $rtbl($res) + } + + do_execsql_test 4.$tn.3 { + SELECT * FROM abc + } {1 one 1 2 two 2 3 xyz 3 4 XYZ 4} + + foreach {tn2 oc res} { + 1 "ON CONFLICT DO NOTHING" 0 + 2 "ON CONFLICT(y) WHERE x='xyz' COLLATE nocase DO NOTHING" 0 + 3 "ON CONFLICT(y) WHERE x='xyz' COLLATE binary DO NOTHING" 2 + 4 "ON CONFLICT(x) WHERE y>0 DO NOTHING" 1 + } { + do_catchsql_test 4.$tn.2.$tn2 " + INSERT INTO abc VALUES(5, 'xYz', 3) $oc + " $rtbl($res) + } +} + +do_catchsql_test 5.0 { + CREATE TABLE w1(a INT PRIMARY KEY, x, y); + CREATE UNIQUE INDEX w1expr ON w1(('x' || x)); + INSERT INTO w1 VALUES(2, 'one', NULL) + ON CONFLICT (('x' || x) COLLATE nocase) DO NOTHING; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} + +#------------------------------------------------------------------------- +# Test that ON CONFLICT constraint processing occurs before any REPLACE +# constraint processing. +# +foreach {tn sql} { + 1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c); + } + 2 { + CREATE TABLE t1(a INT PRIMARY KEY, b UNIQUE, c); + } + 3 { + CREATE TABLE t1(a INT PRIMARY KEY, b UNIQUE, c) WITHOUT ROWID; + } +} { + reset_db + execsql $sql + do_execsql_test 6.1.$tn { + INSERT INTO t1 VALUES(1, 1, 'one'); + INSERT INTO t1 VALUES(2, 2, 'two'); + INSERT OR REPLACE INTO t1 VALUES(1, 2, 'two') ON CONFLICT(b) DO NOTHING; + PRAGMA integrity_check; + } {ok} +} + +foreach {tn sql} { + 1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c UNIQUE); + } +} { + reset_db + execsql $sql + + do_execsql_test 6.2.$tn.1 { + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + } + + do_execsql_test 6.2.$tn.2 { + INSERT OR REPLACE INTO t1 VALUES(3, 1, 1) ON CONFLICT(b) DO NOTHING; + SELECT * FROM t1; + PRAGMA integrity_check; + } {1 1 1 2 2 2 ok} + + do_execsql_test 6.2.$tn.3 { + INSERT OR REPLACE INTO t1 VALUES(3, 2, 2) ON CONFLICT(c) DO NOTHING; + SELECT * FROM t1; + PRAGMA integrity_check; + } {1 1 1 2 2 2 ok} + + do_execsql_test 6.2.$tn.2 { + INSERT OR REPLACE INTO t1 VALUES(3, 1, 1) ON CONFLICT(b) + DO UPDATE SET b=b||'x'; + SELECT * FROM t1; + PRAGMA integrity_check; + } {1 1x 1 2 2 2 ok} + + do_execsql_test 6.2.$tn.2 { + INSERT OR REPLACE INTO t1 VALUES(3, 2, 2) ON CONFLICT(c) + DO UPDATE SET c=c||'x'; + SELECT * FROM t1; + PRAGMA integrity_check; + } {1 1x 1 2 2 2x ok} +} + +#------------------------------------------------------------------------- +# Test references to "excluded". And using an alias in an INSERT +# statement. +# +foreach {tn sql} { + 1 { + CREATE TABLE t1(w, x, y, z, PRIMARY KEY(x, y)); + CREATE UNIQUE INDEX zz ON t1(z); + } + 2 { + CREATE TABLE t1(w, x, y, z, PRIMARY KEY(x, y)) WITHOUT ROWID; + CREATE UNIQUE INDEX zz ON t1(z); + } +} { + reset_db + execsql $sql + do_execsql_test 7.$tn.0 { + INSERT INTO t1 VALUES('a', 1, 1, 1); + INSERT INTO t1 VALUES('b', 2, 2, 2); + } + + do_execsql_test 7.$tn.1 { + INSERT INTO t1 VALUES('c', 3, 3, 1) ON CONFLICT(z) + DO UPDATE SET w = excluded.w; + SELECT * FROM t1; + } {c 1 1 1 b 2 2 2} + + do_execsql_test 7.$tn.2 { + INSERT INTO t1 VALUES('c', 2, 2, 3) ON CONFLICT(y, x) + DO UPDATE SET w = w||w; + SELECT * FROM t1; + } {c 1 1 1 bb 2 2 2} + + do_execsql_test 7.$tn.3 { + INSERT INTO t1 VALUES('c', 2, 2, 3) ON CONFLICT(y, x) + DO UPDATE SET w = w||t1.w; + SELECT * FROM t1; + } {c 1 1 1 bbbb 2 2 2} + + do_execsql_test 7.$tn.4 { + INSERT INTO t1 AS tbl VALUES('c', 2, 2, 3) ON CONFLICT(y, x) + DO UPDATE SET w = w||tbl.w; + SELECT * FROM t1; + } {c 1 1 1 bbbbbbbb 2 2 2} +} + +foreach {tn sql} { + 1 { + CREATE TABLE excluded(w, x INTEGER, 'a b', z, PRIMARY KEY(x, 'a b')); + CREATE UNIQUE INDEX zz ON excluded(z); + CREATE INDEX zz2 ON excluded(z); + } + 2 { + CREATE TABLE excluded(w, x, 'a b', z, PRIMARY KEY(x, 'a b')) WITHOUT ROWID; + CREATE UNIQUE INDEX zz ON excluded(z); + CREATE INDEX zz2 ON excluded(z); + } +} { + reset_db + execsql $sql + do_execsql_test 8.$tn.0 { + INSERT INTO excluded VALUES('a', 1, 1, 1); + INSERT INTO excluded VALUES('b', 2, 2, 2); + } + + # Note: An error in Postgres: "table reference "excluded" is ambiguous". + # + do_execsql_test 8.$tn.1 { + INSERT INTO excluded VALUES('hello', 1, 1, NULL) ON CONFLICT(x, "a b") + DO UPDATE SET w=excluded.w; + SELECT * FROM excluded; + } {a 1 1 1 b 2 2 2} + + do_execsql_test 8.$tn.2 { + INSERT INTO excluded AS x1 VALUES('hello', 1, 1, NULL) ON CONFLICT(x, [a b]) + DO UPDATE SET w=excluded.w; + SELECT * FROM excluded; + } {hello 1 1 1 b 2 2 2} + + do_execsql_test 8.$tn.3 { + INSERT INTO excluded AS x1 VALUES('hello', 1, 1, NULL) ON CONFLICT(x, [a b]) + DO UPDATE SET w=w||w WHERE excluded.w!='hello'; + SELECT * FROM excluded; + } {hello 1 1 1 b 2 2 2} + + do_execsql_test 8.$tn.4 { + INSERT INTO excluded AS x1 VALUES('hello', 1, 1, NULL) ON CONFLICT(x, [a b]) + DO UPDATE SET w=w||w WHERE excluded.x=1; + SELECT * FROM excluded; + } {hellohello 1 1 1 b 2 2 2} + + do_catchsql_test 8.$tn.5 { + INSERT INTO excluded AS x1 VALUES('hello', 1, 1, NULL) + ON CONFLICT(x, [a b]) WHERE y=1 + DO UPDATE SET w=w||w WHERE excluded.x=1; + } {1 {no such column: y}} +} + +#-------------------------------------------------------------------------- +# +do_execsql_test 9.0 { + CREATE TABLE v(x INTEGER); + CREATE TABLE hist(x INTEGER PRIMARY KEY, cnt INTEGER); + CREATE TRIGGER vt AFTER INSERT ON v BEGIN + INSERT INTO hist VALUES(new.x, 1) ON CONFLICT(x) DO + UPDATE SET cnt=cnt+1; + END; +} + +do_execsql_test 9.1 { + INSERT INTO v VALUES(1), (4), (1), (5), (5), (8), (9), (1); + SELECT * FROM hist; +} { + 1 3 + 4 1 + 5 2 + 8 1 + 9 1 +} + + +finish_test diff --git a/test/upsertfault.test b/test/upsertfault.test new file mode 100644 index 0000000000..52bb4a5e35 --- /dev/null +++ b/test/upsertfault.test @@ -0,0 +1,38 @@ +# 2018-04-17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases for UPSERT + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix upsertfault + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c, d, UNIQUE(b, c)); + INSERT INTO t1 VALUES(1, 1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2, 2); +} +faultsim_save_and_close + +do_faultsim_test 1 -faults oom* -prep { + faultsim_restore_and_reopen + db eval { SELECT * FROM sqlite_master } +} -body { + execsql { + INSERT INTO t1 VALUES(3, 2, 2, NULL) ON CONFLICT(b, c) DO + UPDATE SET d=d+1; + } +} -test { + faultsim_test_result {0 {}} +} + + +finish_test diff --git a/test/vacuum4.test b/test/vacuum4.test index 326d037276..bbf0dd4379 100644 --- a/test/vacuum4.test +++ b/test/vacuum4.test @@ -65,3 +65,5 @@ do_test vacuum4-1.1 { VACUUM; } } {} + +finish_test diff --git a/test/vacuum5.test b/test/vacuum5.test index 8e76a9393c..f203fb87ba 100644 --- a/test/vacuum5.test +++ b/test/vacuum5.test @@ -143,9 +143,11 @@ if {$::TEMP_STORE<3 && [permutation]!="inmemory_journal"} { db close tvfs delete - do_test 3.2 { - lrange $::openfiles 0 4 - } {test.db test.db-journal test.db-journal {} test.db-journal} + if {[atomic_batch_write test.db]==0} { + do_test 3.2 { + lrange $::openfiles 0 4 + } {test.db test.db-journal test.db-journal {} test.db-journal} + } } diff --git a/test/varint.test b/test/varint.test index 974e88f2a6..fd0ec0d415 100644 --- a/test/varint.test +++ b/test/varint.test @@ -30,3 +30,5 @@ foreach start {0 100 10000 1000000 0x10000000} { } } } + +finish_test diff --git a/test/view.test b/test/view.test index 694b3c6abd..59ff55c692 100644 --- a/test/view.test +++ b/test/view.test @@ -674,5 +674,31 @@ do_test view-22.2 { lsort [array names x] } {{} * :1 :2} +do_test view-25.1 { + db eval { + CREATE TABLE t25 (x); + INSERT INTO t25 (x) VALUES (1); + ANALYZE; + } + proc authLogDelete {code arg1 arg2 arg3 arg4 args} { + if {$code=="SQLITE_DELETE" && [string match sqlite_stat* $arg1]} { + # lappend ::log [list $code $arg1 $arg2 $arg3 $arg4 $args] + lappend ::log [list $code $arg1 $arg2 $arg3 $arg4] + } + return SQLITE_OK + } + set log "" + db authorizer ::authLogDelete + db eval {DROP VIEW x1;} + set log +} {} + +set res [list {SQLITE_DELETE sqlite_stat1 {} main {}}] +ifcapable stat4 { lappend res {SQLITE_DELETE sqlite_stat4 {} main {}} } +do_test view-25.2 { + set log "" + db eval {DROP TABLE t25;} + set log +} $res finish_test diff --git a/test/vtab2.test b/test/vtab2.test index f0616513bd..7bd27a5fd0 100644 --- a/test/vtab2.test +++ b/test/vtab2.test @@ -60,7 +60,7 @@ do_test vtab2-2.1 { set ::abc 123 execsql { CREATE VIRTUAL TABLE vars USING tclvar; - SELECT * FROM vars WHERE name='abc'; + SELECT name, arrayname, value FROM vars WHERE name='abc'; } } [list abc "" 123] do_test vtab2-2.2 { @@ -68,7 +68,7 @@ do_test vtab2-2.2 { set A(2) 4 set A(3) 9 execsql { - SELECT * FROM vars WHERE name='A'; + SELECT name, arrayname, value FROM vars WHERE name='A'; } } [list A 1 1 A 2 4 A 3 9] unset -nocomplain result diff --git a/test/vtabE.test b/test/vtabE.test index aeb478e3e8..cbb6a1e30a 100644 --- a/test/vtabE.test +++ b/test/vtabE.test @@ -39,7 +39,9 @@ do_test vtabE-1 { CREATE VIRTUAL TABLE t1 USING tclvar; CREATE VIRTUAL TABLE t2 USING tclvar; CREATE TABLE t3(a INTEGER PRIMARY KEY, b); - SELECT t1.*, t2.*, abs(t3.b + abs(t2.value + abs(t1.value))) + SELECT t1.name, t1.arrayname, t1.value, + t2.name, t2.arrayname, t2.value, + abs(t3.b + abs(t2.value + abs(t1.value))) FROM t1 LEFT JOIN t2 ON t2.name = t1.arrayname LEFT JOIN t3 ON t3.a=t2.value WHERE t1.name = 'vtabE' diff --git a/test/vtabH.test b/test/vtabH.test index 2ebc3f9cc3..56c12544f8 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -55,7 +55,7 @@ register_tclvar_module db set ::xyz 10 do_execsql_test 2.0 { CREATE VIRTUAL TABLE vars USING tclvar; - SELECT * FROM vars WHERE name = 'xyz'; + SELECT name, arrayname, value FROM vars WHERE name = 'xyz'; } {xyz {} 10} set x1 aback diff --git a/test/vtabJ.test b/test/vtabJ.test new file mode 100644 index 0000000000..fb544827c3 --- /dev/null +++ b/test/vtabJ.test @@ -0,0 +1,126 @@ +# 2017-08-10 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements tests of writing to WITHOUT ROWID virtual tables +# using the tclvar eponymous virtual table. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix vtabJ + +ifcapable !vtab { + finish_test + return +} + +register_tclvar_module db + +unset -nocomplain vtabJ +do_test 100 { + set vtabJ(1) this + set vtabJ(two) is + set vtabJ(3) {a test} + db eval { + SELECT fullname, value FROM tclvar WHERE name='vtabJ' ORDER BY fullname; + } +} {vtabJ(1) this vtabJ(3) {a test} vtabJ(two) is} + +do_execsql_test 110 { + INSERT INTO tclvar(fullname, value) + VALUES('vtabJ(4)',4),('vtabJ(five)',555); + SELECT fullname, value FROM tclvar WHERE name='vtabJ' ORDER BY fullname; +} {vtabJ(1) this vtabJ(3) {a test} vtabJ(4) 4 vtabJ(five) 555 vtabJ(two) is} +do_test 111 { + set res {} + foreach vname [lsort [array names vtabJ]] { + lappend res vtabJ($vname) $vtabJ($vname) + } + set res +} {vtabJ(1) this vtabJ(3) {a test} vtabJ(4) 4 vtabJ(five) 555 vtabJ(two) is} + +do_test 120 { + db eval { + INSERT INTO tclvar(fullname, value) VALUES('vtabJ(4)',444); + } + set vtabJ(4) +} {444} + +do_test 130 { + db eval { + INSERT INTO tclvar(fullname, value) VALUES('vtabJ(4)',NULL); + } + info exists vtabJ(4) +} {0} + +do_test 140 { + db eval { + UPDATE tclvar SET value=55 WHERE fullname='vtabJ(five)'; + } + set vtabJ(five) +} {55} + +do_test 150 { + db eval { + UPDATE tclvar SET fullname='vtabJ(5)' WHERE fullname='vtabJ(five)'; + } + set vtabJ(5) +} {55} +do_test 151 { + info exists vtabJ(five) +} {0} +do_test 152 { + set res {} + foreach vname [lsort [array names vtabJ]] { + lappend res vtabJ($vname) $vtabJ($vname) + } + set res +} {vtabJ(1) this vtabJ(3) {a test} vtabJ(5) 55 vtabJ(two) is} + +do_execsql_test 160 { + SELECT fullname FROM tclvar WHERE arrayname='two' +} {vtabJ(two)} +do_execsql_test 161 { + DELETE FROM tclvar WHERE arrayname='two'; + SELECT fullname, value FROM tclvar WHERE name='vtabJ' ORDER BY fullname; +} {vtabJ(1) this vtabJ(3) {a test} vtabJ(5) 55} +do_test 162 { + set res {} + foreach vname [lsort [array names vtabJ]] { + lappend res vtabJ($vname) $vtabJ($vname) + } + set res +} {vtabJ(1) this vtabJ(3) {a test} vtabJ(5) 55} + +# Try to trick the module into updating the same variable twice for a +# single UPDATE statement. +# +do_execsql_test 171 { + INSERT INTO tclvar(fullname, value) VALUES('xx', 'a'); + SELECT name, value FROM tclvar where name = 'xx'; +} {xx a} +do_execsql_test 172 { + UPDATE tclvar SET value = value || 't' + WHERE name = 'xx' OR name = 'x'||'x'; + SELECT name, value FROM tclvar where name = 'xx'; +} {xx at} +do_execsql_test 173 { + UPDATE tclvar SET value = value || 't' + WHERE name = 'xx' OR name BETWEEN 'xx' AND 'xx'; + SELECT name, value FROM tclvar where name = 'xx'; +} {xx att} + +do_execsql_test 181 { + DELETE FROM tclvar WHERE name BETWEEN 'xx' AND 'xx' OR name='xx'; + SELECT name, value FROM tclvar where name = 'xx'; +} {} + + +finish_test diff --git a/test/vtab_err.test b/test/vtab_err.test index 068386eb31..cb40acdbfc 100644 --- a/test/vtab_err.test +++ b/test/vtab_err.test @@ -40,11 +40,6 @@ do_ioerr_test vtab_err-1 -tclprep { COMMIT; } -ifcapable !memdebug { - puts "Skipping vtab_err-2 tests: not compiled with -DSQLITE_MEMDEBUG..." - finish_test - return -} source $testdir/malloc_common.tcl diff --git a/test/wal2.test b/test/wal2.test index 0b15b15461..b26f5ca877 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -122,8 +122,8 @@ do_test wal2-1.1 { } {4 10} set RECOVER [list \ - {0 1 lock exclusive} {1 7 lock exclusive} \ - {1 7 unlock exclusive} {0 1 unlock exclusive} \ + {0 1 lock exclusive} {1 2 lock exclusive} {4 4 lock exclusive} \ + {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive} \ ] set READ [list \ {4 1 lock shared} {4 1 unlock shared} \ @@ -393,8 +393,10 @@ tvfs delete set expected_locks [list] lappend expected_locks {1 1 lock exclusive} ;# Lock checkpoint lappend expected_locks {0 1 lock exclusive} ;# Lock writer -lappend expected_locks {2 6 lock exclusive} ;# Lock recovery & all aReadMark[] -lappend expected_locks {2 6 unlock exclusive} ;# Unlock recovery & aReadMark[] +lappend expected_locks {2 1 lock exclusive} ;# Lock recovery +lappend expected_locks {4 4 lock exclusive} ;# Lock all aReadMark[] +lappend expected_locks {2 1 unlock exclusive} ;# Unlock recovery +lappend expected_locks {4 4 unlock exclusive} ;# Unlock all aReadMark[] lappend expected_locks {0 1 unlock exclusive} ;# Unlock writer lappend expected_locks {3 1 lock exclusive} ;# Lock aReadMark[0] lappend expected_locks {3 1 unlock exclusive} ;# Unlock aReadMark[0] @@ -582,15 +584,23 @@ do_test wal2-6.3.4 { BEGIN; INSERT INTO t1 VALUES('Groucho'); } - list [file exists test.db-wal] [file exists test.db-journal] -} {0 1} +} {} +if {[atomic_batch_write test.db]==0} { + do_test wal2-6.3.4.1 { + list [file exists test.db-wal] [file exists test.db-journal] + } {0 1} +} do_test wal2-6.3.5 { execsql { PRAGMA lock_status } } {main exclusive temp closed} do_test wal2-6.3.6 { execsql { COMMIT } - list [file exists test.db-wal] [file exists test.db-journal] -} {0 1} +} {} +if {[atomic_batch_write test.db]==0} { + do_test wal2-6.3.6.1 { + list [file exists test.db-wal] [file exists test.db-journal] + } {0 1} +} do_test wal2-6.3.7 { execsql { PRAGMA lock_status } } {main exclusive temp closed} @@ -615,8 +625,8 @@ do_test wal2-6.4.1 { } {} set RECOVERY { - {0 1 lock exclusive} {1 7 lock exclusive} - {1 7 unlock exclusive} {0 1 unlock exclusive} + {0 1 lock exclusive} {1 2 lock exclusive} {4 4 lock exclusive} + {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive} } set READMARK0_READ { {3 1 lock shared} {3 1 unlock shared} @@ -1128,7 +1138,7 @@ if {$::tcl_platform(platform) == "unix"} { foreach {tn db_perm wal_perm shm_perm can_open can_read can_write} { 2 00644 00644 00644 1 1 1 3 00644 00400 00644 1 1 0 - 4 00644 00644 00400 1 0 0 + 4 00644 00644 00400 1 1 0 5 00400 00644 00644 1 1 0 7 00644 00000 00644 1 0 0 @@ -1191,7 +1201,7 @@ if {$::tcl_platform(platform) == "unix"} { # foreach {tn sql reslist} { 1 { } {10 0 4 0 6 0} - 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} + 2 { PRAGMA checkpoint_fullfsync = 1 } {10 6 4 3 6 3} 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} } { ifcapable default_ckptfullfsync { @@ -1261,8 +1271,8 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} { 6 {0 1 full} {0 2} {0 1} {0 2} 7 {1 0 off} {0 0} {0 0} {0 0} - 8 {1 0 normal} {1 0} {0 0} {0 2} - 9 {1 0 full} {2 0} {1 0} {0 2} + 8 {1 0 normal} {0 1} {0 0} {0 2} + 9 {1 0 full} {1 1} {1 0} {0 2} 10 {1 1 off} {0 0} {0 0} {0 0} 11 {1 1 normal} {0 1} {0 0} {0 2} diff --git a/test/walfault.test b/test/walfault.test index 4e7064d53b..6cb760b258 100644 --- a/test/walfault.test +++ b/test/walfault.test @@ -552,7 +552,7 @@ do_faultsim_test walfault-14 -prep { #------------------------------------------------------------------------- # Test fault-handling when switching out of exclusive-locking mode. # -do_test walfault-14-pre { +do_test walfault-15-pre { faultsim_delete_and_reopen execsql { PRAGMA auto_vacuum = 0; @@ -565,7 +565,7 @@ do_test walfault-14-pre { } faultsim_save_and_close } {} -do_faultsim_test walfault-14 -prep { +do_faultsim_test walfault-15 -prep { faultsim_restore_and_reopen execsql { SELECT count(*) FROM abc; diff --git a/test/walmode.test b/test/walmode.test index 4e14d54d4f..f760823c8d 100644 --- a/test/walmode.test +++ b/test/walmode.test @@ -45,15 +45,17 @@ do_test walmode-1.2 { file size test.db } {1024} -set expected_sync_count 3 -if {$::tcl_platform(platform)!="windows"} { - ifcapable dirsync { - incr expected_sync_count +if {[atomic_batch_write test.db]==0} { + set expected_sync_count 3 + if {$::tcl_platform(platform)!="windows"} { + ifcapable dirsync { + incr expected_sync_count + } } + do_test walmode-1.3 { + set sqlite_sync_count + } $expected_sync_count } -do_test walmode-1.3 { - set sqlite_sync_count -} $expected_sync_count do_test walmode-1.4 { file exists test.db-wal @@ -106,9 +108,11 @@ do_test walmode-4.1 { execsql { INSERT INTO t1 VALUES(1, 2) } execsql { PRAGMA journal_mode = persist } } {persist} -do_test walmode-4.2 { - list [file exists test.db-journal] [file exists test.db-wal] -} {1 0} +if {[atomic_batch_write test.db]==0} { + do_test walmode-4.2 { + list [file exists test.db-journal] [file exists test.db-wal] + } {1 0} +} do_test walmode-4.3 { execsql { SELECT * FROM t1 } } {1 2} @@ -117,9 +121,11 @@ do_test walmode-4.4 { sqlite3 db test.db execsql { SELECT * FROM t1 } } {1 2} -do_test walmode-4.5 { - list [file exists test.db-journal] [file exists test.db-wal] -} {1 0} +if {[atomic_batch_write test.db]==0} { + do_test walmode-4.5 { + list [file exists test.db-journal] [file exists test.db-wal] + } {1 0} +} # Test that nothing goes wrong if a connection is prevented from changing # from WAL to rollback mode because a second connection has the database diff --git a/test/walprotocol.test b/test/walprotocol.test index ee8d0b72a5..b1d9e8c01f 100644 --- a/test/walprotocol.test +++ b/test/walprotocol.test @@ -52,21 +52,21 @@ do_test 1.1 { set ::locks [list] sqlite3 db test.db -vfs T execsql { SELECT * FROM x } - lrange $::locks 0 3 -} [list {0 1 lock exclusive} {1 7 lock exclusive} \ - {1 7 unlock exclusive} {0 1 unlock exclusive} \ + lrange $::locks 0 5 +} [list {0 1 lock exclusive} {1 2 lock exclusive} {4 4 lock exclusive} \ + {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive} \ ] do_test 1.2 { db close set ::locks [list] sqlite3 db test.db -vfs T execsql { SELECT * FROM x } - lrange $::locks 0 3 -} [list {0 1 lock exclusive} {1 7 lock exclusive} \ - {1 7 unlock exclusive} {0 1 unlock exclusive} \ + lrange $::locks 0 5 +} [list {0 1 lock exclusive} {1 2 lock exclusive} {4 4 lock exclusive} \ + {1 2 unlock exclusive} {4 4 unlock exclusive} {0 1 unlock exclusive} \ ] proc lock_callback {method filename handle lock} { - if {$lock == "1 7 lock exclusive"} { return SQLITE_BUSY } + if {$lock == "1 2 lock exclusive"} { return SQLITE_BUSY } return SQLITE_OK } puts "# Warning: This next test case causes SQLite to call xSleep(1) 100 times." @@ -90,6 +90,18 @@ do_test 1.4 { sqlite3 db test.db -vfs T catchsql { SELECT * FROM x } } {1 {locking protocol}} + +puts "# Warning: Third time!" +proc lock_callback {method filename handle lock} { + if {$lock == "4 4 lock exclusive"} { return SQLITE_BUSY } + return SQLITE_OK +} +do_test 1.5 { + db close + set ::locks [list] + sqlite3 db test.db -vfs T + catchsql { SELECT * FROM x } +} {1 {locking protocol}} db close T delete @@ -135,13 +147,14 @@ T filter xShmLock T script lock_callback proc lock_callback {method file handle spec} { - if {$spec == "1 7 unlock exclusive"} { + if {$spec == "1 2 unlock exclusive"} { T filter {} set ::r [catchsql { SELECT * FROM b } db2] } } sqlite3 db test.db sqlite3 db2 test.db +puts "# Warning: Another slow test!" do_test 2.5 { execsql { SELECT * FROM b } } {Tehran Qom Markazi Qazvin Gilan Ardabil} @@ -157,12 +170,13 @@ sqlite3 db2 test.db T filter xShmLock T script lock_callback proc lock_callback {method file handle spec} { - if {$spec == "1 7 unlock exclusive"} { + if {$spec == "1 2 unlock exclusive"} { T filter {} set ::r [catchsql { SELECT * FROM b } db2] } } unset ::r +puts "# Warning: Last one!" do_test 2.7 { execsql { SELECT * FROM b } } {Tehran Qom Markazi Qazvin Gilan Ardabil} diff --git a/test/walprotocol2.test b/test/walprotocol2.test new file mode 100644 index 0000000000..0792c9aae0 --- /dev/null +++ b/test/walprotocol2.test @@ -0,0 +1,97 @@ +# 2018 July 4 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/wal_common.tcl +ifcapable !wal {finish_test ; return } + +set testprefix walprotocol2 + +#------------------------------------------------------------------------- +# When recovering the contents of a WAL file, a process obtains the WRITER +# lock, then locks all other bytes before commencing recovery. If it fails +# to lock all other bytes (because some other process is holding a read +# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the +# caller. Test this (test case 1.3). +# +# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain +# the WRITER lock (should be the same). Test case 1.4. +# +do_execsql_test 1.0 { + PRAGMA journal_mode = wal; + CREATE TABLE x(y); + INSERT INTO x VALUES('z'); +} {wal} + +db close + +proc lock_callback {method filename handle lock} { + # puts "$method $filename $handle $lock" +} +testvfs T +T filter xShmLock +T script lock_callback + +sqlite3 db test.db -vfs T +sqlite3 db2 test.db -vfs T + +do_execsql_test 2.0 { + SELECT * FROM x; +} {z} +do_execsql_test -db db2 2.1 { + SELECT * FROM x; +} {z} + +#--------------------------------------------------------------- +# Attempt a "BEGIN EXCLUSIVE" using connection handle [db]. This +# causes SQLite to open a read transaction, then a write transaction. +# Rig the xShmLock() callback so that just before the EXCLUSIVE lock +# for the write transaction is taken, connection [db2] jumps in and +# modifies the database. This causes the "BEGIN EXCLUSIVE" to throw +# an SQLITE_BUSY_SNAPSHOT error. +# +proc lock_callback {method filename handle lock} { + if {$lock=="0 1 lock exclusive"} { + proc lock_callback {method filename handle lock} {} + db2 eval { INSERT INTO x VALUES('y') } + } +} +do_catchsql_test 2.2 { + BEGIN EXCLUSIVE; +} {1 {database is locked}} +do_test 2.3 { + sqlite3_extended_errcode db +} {SQLITE_BUSY} + +#--------------------------------------------------------------- +# Same again, but with a busy-handler. This time, following the +# SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the +# whole thing retried from the beginning. This time it succeeds. +# +proc lock_callback {method filename handle lock} { + if {$lock=="0 1 lock exclusive"} { + proc lock_callback {method filename handle lock} {} + db2 eval { INSERT INTO x VALUES('x') } + } +} +db timeout 10 +do_catchsql_test 2.4 { + BEGIN EXCLUSIVE; +} {0 {}} +do_execsql_test 2.5 { + SELECT * FROM x; + COMMIT; +} {z y x} + +finish_test diff --git a/test/walro.test b/test/walro.test index f46e44d4cb..cae52db6d3 100644 --- a/test/walro.test +++ b/test/walro.test @@ -101,10 +101,11 @@ do_multiclient_test tn { code1 { db close } list [file exists test.db-wal] [file exists test.db-shm] } {1 1} + do_test 1.2.2 { code1 { sqlite3 db file:test.db?readonly_shm=1 } - sql1 { SELECT * FROM t1 } - } {a b c d e f g h i j} + list [catch { sql1 { SELECT * FROM t1 } } msg] $msg + } {0 {a b c d e f g h i j}} do_test 1.2.3 { code1 { db close } @@ -113,10 +114,10 @@ do_multiclient_test tn { file attributes test.db-shm -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM t1 } - } {1 {attempt to write a readonly database}} + } {0 {a b c d e f g h i j}} do_test 1.2.4 { code1 { sqlite3_extended_errcode db } - } {SQLITE_READONLY_RECOVERY} + } {SQLITE_OK} do_test 1.2.5 { file attributes test.db-shm -permissions rw-r--r-- @@ -138,11 +139,15 @@ do_multiclient_test tn { # Now check that if the readonly_shm option is not supplied, or if it # is set to zero, it is not possible to connect to the database without # read-write access to the shm. + # + # UPDATE: os_unix.c now opens the *-shm file in readonly mode + # automatically. + # do_test 1.3.1 { code1 { db close } code1 { sqlite3 db test.db } csql1 { SELECT * FROM t1 } - } {1 {unable to open database file}} + } {0 {a b c d e f g h i j k l}} # Also test that if the -shm file can be opened for read/write access, # it is not if readonly_shm=1 is present in the URI. @@ -161,10 +166,10 @@ do_multiclient_test tn { file attributes test.db-shm -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM t1 } - } {1 {attempt to write a readonly database}} + } {0 {a b c d e f g h i j k l}} do_test 1.3.2.4 { code1 { sqlite3_extended_errcode db } - } {SQLITE_READONLY_RECOVERY} + } {SQLITE_OK} #----------------------------------------------------------------------- # Test cases 1.4.* check that checkpoints and log wraps don't prevent diff --git a/test/walro2.test b/test/walro2.test new file mode 100644 index 0000000000..34408c1695 --- /dev/null +++ b/test/walro2.test @@ -0,0 +1,406 @@ +# 2011 May 09 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for using WAL databases in read-only mode. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/wal_common.tcl +set ::testprefix walro2 + +# And only if the build is WAL-capable. +# +ifcapable !wal { + finish_test + return +} + +proc copy_to_test2 {bZeroShm} { + forcecopy test.db test.db2 + forcecopy test.db-wal test.db2-wal + if {$bZeroShm} { + forcedelete test.db2-shm + set fd [open test.db2-shm w] + seek $fd [expr [file size test.db-shm]-1] + puts -nonewline $fd "\0" + close $fd + } else { + forcecopy test.db-shm test.db2-shm + } +} + +# Most systems allocate the *-shm file in 32KB trunks. But on UNIX systems +# for which the getpagesize() call returns greater than 32K, the *-shm +# file is allocated in page-sized units (since you cannot mmap part of +# a page). The following code sets variable $MINSHMSZ to the smallest +# possible *-shm file (i.e. the greater of 32KB and the system page-size). +# +do_execsql_test 0.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); +} {wal} +set MINSHMSZ [file size test.db-shm] + +foreach bZeroShm {0 1} { +set TN [expr $bZeroShm+1] +do_multiclient_test tn { + + # Close all connections and delete the database. + # + code1 { db close } + code2 { db2 close } + code3 { db3 close } + forcedelete test.db + + # Do not run tests with the connections in the same process. + # + if {$tn==2} continue + + foreach c {code1 code2 code3} { + $c { + sqlite3_shutdown + sqlite3_config_uri 1 + } + } + + do_test $TN.1.1 { + code2 { sqlite3 db2 test.db } + sql2 { + CREATE TABLE t1(x, y); + PRAGMA journal_mode = WAL; + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t1 VALUES('c', 'd'); + } + file exists test.db-shm + } {1} + + do_test $TN.1.2.1 { + copy_to_test2 $bZeroShm + code1 { + sqlite3 db file:test.db2?readonly_shm=1 + } + + sql1 { SELECT * FROM t1 } + } {a b c d} + do_test $TN.1.2.2 { + sql1 { SELECT * FROM t1 } + } {a b c d} + + do_test $TN.1.3.1 { + code3 { sqlite3 db3 test.db2 } + sql3 { SELECT * FROM t1 } + } {a b c d} + + do_test $TN.1.3.2 { + sql1 { SELECT * FROM t1 } + } {a b c d} + + code1 { db close } + code2 { db2 close } + code3 { db3 close } + + do_test $TN.2.1 { + code2 { sqlite3 db2 test.db } + sql2 { + INSERT INTO t1 VALUES('e', 'f'); + INSERT INTO t1 VALUES('g', 'h'); + } + file exists test.db-shm + } {1} + + do_test $TN.2.2 { + copy_to_test2 $bZeroShm + code1 { + sqlite3 db file:test.db2?readonly_shm=1 + } + sql1 { + BEGIN; + SELECT * FROM t1; + } + } {a b c d e f g h} + + do_test $TN.2.3.1 { + code3 { sqlite3 db3 test.db2 } + sql3 { SELECT * FROM t1 } + } {a b c d e f g h} + do_test $TN.2.3.2 { + sql3 { INSERT INTO t1 VALUES('i', 'j') } + code3 { db3 close } + sql1 { COMMIT } + } {} + do_test $TN.2.3.3 { + sql1 { SELECT * FROM t1 } + } {a b c d e f g h i j} + + + #----------------------------------------------------------------------- + # 3.1.*: That a readonly_shm connection can read a database file if both + # the *-wal and *-shm files are zero bytes in size. + # + # 3.2.*: That it flushes the cache if, between transactions on a db with a + # zero byte *-wal file, some other connection modifies the db, then + # does "PRAGMA wal_checkpoint=truncate" to truncate the wal file + # back to zero bytes in size. + # + # 3.3.*: That, if between transactions some other process wraps the wal + # file, the readonly_shm client reruns recovery. + # + catch { code1 { db close } } + catch { code2 { db2 close } } + catch { code3 { db3 close } } + do_test $TN.3.1.0 { + list [file exists test.db-wal] [file exists test.db-shm] + } {0 0} + do_test $TN.3.1.1 { + close [open test.db-wal w] + close [open test.db-shm w] + code1 { + sqlite3 db file:test.db?readonly_shm=1 + } + sql1 { SELECT * FROM t1 } + } {a b c d e f g h} + + do_test $TN.3.2.0 { + list [file size test.db-wal] [file size test.db-shm] + } {0 0} + do_test $TN.3.2.1 { + code2 { sqlite3 db2 test.db } + sql2 { INSERT INTO t1 VALUES(1, 2) ; PRAGMA wal_checkpoint=truncate } + code2 { db2 close } + sql1 { SELECT * FROM t1 } + } {a b c d e f g h 1 2} + do_test $TN.3.2.2 { + list [file size test.db-wal] [file size test.db-shm] + } [list 0 $MINSHMSZ] + + do_test $TN.3.3.0 { + code2 { sqlite3 db2 test.db } + sql2 { + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + INSERT INTO t1 VALUES(9, 10); + } + code2 { db2 close } + code1 { db close } + list [file size test.db-wal] [file size test.db-shm] + } [list [wal_file_size 4 1024] $MINSHMSZ] + do_test $TN.3.3.1 { + code1 { sqlite3 db file:test.db?readonly_shm=1 } + sql1 { SELECT * FROM t1 } + } {a b c d e f g h 1 2 3 4 5 6 7 8 9 10} + do_test $TN.3.3.2 { + code2 { sqlite3 db2 test.db } + sql2 { + PRAGMA wal_checkpoint; + DELETE FROM t1; + INSERT INTO t1 VALUES('i', 'ii'); + } + code2 { db2 close } + list [file size test.db-wal] [file size test.db-shm] + } [list [wal_file_size 4 1024] $MINSHMSZ] + do_test $TN.3.3.3 { + sql1 { SELECT * FROM t1 } + } {i ii} + + #----------------------------------------------------------------------- + # + # + catch { code1 { db close } } + catch { code2 { db2 close } } + catch { code3 { db3 close } } + + do_test $TN.4.0 { + code1 { forcedelete test.db } + code1 { sqlite3 db test.db } + sql1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('hello'); + INSERT INTO t1 VALUES('world'); + } + + copy_to_test2 $bZeroShm + + code1 { db close } + } {} + + do_test $TN.4.1.1 { + code2 { sqlite3 db2 file:test.db2?readonly_shm=1 } + sql2 { SELECT * FROM t1 } + } {hello world} + + do_test $TN.4.1.2 { + code3 { sqlite3 db3 test.db2 } + sql3 { + INSERT INTO t1 VALUES('!'); + PRAGMA wal_checkpoint = truncate; + } + code3 { db3 close } + } {} + do_test $TN.4.1.3 { + sql2 { SELECT * FROM t1 } + } {hello world !} + + catch { code1 { db close } } + catch { code2 { db2 close } } + catch { code3 { db3 close } } + + do_test $TN.4.2.1 { + code1 { sqlite3 db test.db } + sql1 { + INSERT INTO t1 VALUES('!'); + INSERT INTO t1 VALUES('!'); + + PRAGMA cache_size = 10; + CREATE TABLE t2(x); + + BEGIN; + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500 + ) + INSERT INTO t2 SELECT randomblob(500) FROM s; + SELECT count(*) FROM t2; + } + } {500} + set sz [file size test.db-wal] + do_test $TN.4.2.2.(sz=$sz) { + expr {$sz>400000} + } {1} + do_test $TN.4.2.4 { + file_control_persist_wal db 1; db close + + copy_to_test2 $bZeroShm + code2 { sqlite3 db2 file:test.db2?readonly_shm=1 } + sql2 { + SELECT * FROM t1; + SELECT count(*) FROM t2; + } + } {hello world ! ! 0} + + #----------------------------------------------------------------------- + # + # + catch { code1 { db close } } + catch { code2 { db2 close } } + catch { code3 { db3 close } } + + do_test $TN.5.0 { + code1 { forcedelete test.db } + code1 { sqlite3 db test.db } + sql1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('hello'); + INSERT INTO t1 VALUES('world'); + INSERT INTO t1 VALUES('!'); + INSERT INTO t1 VALUES('world'); + INSERT INTO t1 VALUES('hello'); + } + + copy_to_test2 $bZeroShm + + code1 { db close } + } {} + + do_test $TN.5.1 { + code2 { sqlite3 db2 file:test.db2?readonly_shm=1 } + sql2 { + SELECT * FROM t1; + } + } {hello world ! world hello} + + do_test $TN.5.2 { + code1 { + proc handle_read {op args} { + if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} { + set ::res2 [sql2 { SELECT * FROM t1 }] + } + puts "$msg xRead $args" + return "SQLITE_OK" + } + testvfs tvfs -fullshm 1 + + sqlite3 db file:test.db2?vfs=tvfs + db eval { SELECT * FROM sqlite_master } + + tvfs filter xRead + tvfs script handle_read + } + sql1 { + PRAGMA wal_checkpoint = truncate; + } + code1 { set ::res2 } + } {hello world ! world hello} + + do_test $TN.5.3 { + code1 { db close } + code1 { tvfs delete } + } {} + + #----------------------------------------------------------------------- + # + # + catch { code1 { db close } } + catch { code2 { db2 close } } + catch { code3 { db3 close } } + + do_test $TN.6.1 { + code1 { forcedelete test.db } + code1 { sqlite3 db test.db } + sql1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('hello'); + INSERT INTO t1 VALUES('world'); + INSERT INTO t1 VALUES('!'); + INSERT INTO t1 VALUES('world'); + INSERT INTO t1 VALUES('hello'); + } + + copy_to_test2 $bZeroShm + + code1 { db close } + } {} + + do_test $TN.6.2 { + code1 { + set ::nRem 5 + proc handle_read {op args} { + if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} { + incr ::nRem -1 + if {$::nRem==0} { + code2 { sqlite3 db2 test.db2 } + sql2 { PRAGMA wal_checkpoint = truncate } + } + } + return "SQLITE_OK" + } + testvfs tvfs -fullshm 1 + + tvfs filter xRead + tvfs script handle_read + + sqlite3 db file:test.db2?readonly_shm=1&vfs=tvfs + db eval { SELECT * FROM t1 } + } + } {hello world ! world hello} + + do_test $TN.6.3 { + code1 { db close } + code1 { tvfs delete } + } {} +} +} ;# foreach bZeroShm + +finish_test diff --git a/test/walrofault.test b/test/walrofault.test new file mode 100644 index 0000000000..3e66e2d920 --- /dev/null +++ b/test/walrofault.test @@ -0,0 +1,60 @@ +# 2011 May 09 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for using WAL databases in read-only mode. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set ::testprefix walro2 + +# And only if the build is WAL-capable. +# +ifcapable !wal { + finish_test + return +} + +db close +sqlite3_shutdown +sqlite3_config_uri 1 +sqlite3 db test.db + +do_execsql_test 1.0 { + CREATE TABLE t1(b); + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES('hello'); + INSERT INTO t1 VALUES('world'); + INSERT INTO t1 VALUES('!'); + INSERT INTO t1 VALUES('world'); + INSERT INTO t1 VALUES('hello'); + PRAGMA cache_size = 10; + BEGIN; + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<30 ) + INSERT INTO t1(b) SELECT randomblob(800) FROM s; +} {wal} +file_control_persist_wal db 1; db close +faultsim_save_and_close + +do_faultsim_test 1 -faults oom* -prep { + catch { db close } + faultsim_restore + sqlite3 db file:test.db?readonly_shm=1 +} -body { + execsql { SELECT * FROM t1 } +} -test { + faultsim_test_result {0 {hello world ! world hello}} +} + + + +finish_test diff --git a/test/walthread.test b/test/walthread.test index 6249ce11af..8e5df9e589 100644 --- a/test/walthread.test +++ b/test/walthread.test @@ -327,59 +327,61 @@ do_thread_test2 walthread-1 -seconds $seconds(walthread-1) -init { # the number of write-transactions performed using a rollback journal. # For example, "192 w, 185 r". # -do_thread_test2 walthread-2 -seconds $seconds(walthread-2) -init { - execsql { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE) } -} -thread RB 2 { +if {[atomic_batch_write test.db]==0} { + do_thread_test2 walthread-2 -seconds $seconds(walthread-2) -init { + execsql { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE) } + } -thread RB 2 { - db close - set nRun 0 - set nDel 0 - while {[tt_continue]} { - sqlite3 db test.db - db busy busyhandler - db eval { SELECT * FROM sqlite_master } - catch { db eval { PRAGMA journal_mode = DELETE } } - db eval { - BEGIN; - INSERT INTO t1 VALUES(NULL, randomblob(100+$E(pid))); - } - incr nRun 1 - incr nDel [file exists test.db-journal] - if {[file exists test.db-journal] + [file exists test.db-wal] != 1} { - error "File-system looks bad..." - } - db eval COMMIT - - integrity_check db close - } - list $nRun $nDel - set {} "[expr $nRun-$nDel] w, $nDel r" - -} -thread WAL 2 { - db close - set nRun 0 - set nDel 0 - while {[tt_continue]} { - sqlite3 db test.db - db busy busyhandler - db eval { SELECT * FROM sqlite_master } - catch { db eval { PRAGMA journal_mode = WAL } } - db eval { - BEGIN; - INSERT INTO t1 VALUES(NULL, randomblob(110+$E(pid))); + set nRun 0 + set nDel 0 + while {[tt_continue]} { + sqlite3 db test.db + db busy busyhandler + db eval { SELECT * FROM sqlite_master } + catch { db eval { PRAGMA journal_mode = DELETE } } + db eval { + BEGIN; + INSERT INTO t1 VALUES(NULL, randomblob(100+$E(pid))); + } + incr nRun 1 + incr nDel [file exists test.db-journal] + if {[file exists test.db-journal] + [file exists test.db-wal] != 1} { + error "File-system looks bad..." + } + db eval COMMIT + + integrity_check + db close } - incr nRun 1 - incr nDel [file exists test.db-journal] - if {[file exists test.db-journal] + [file exists test.db-wal] != 1} { - error "File-system looks bad..." - } - db eval COMMIT - - integrity_check + list $nRun $nDel + set {} "[expr $nRun-$nDel] w, $nDel r" + + } -thread WAL 2 { db close + set nRun 0 + set nDel 0 + while {[tt_continue]} { + sqlite3 db test.db + db busy busyhandler + db eval { SELECT * FROM sqlite_master } + catch { db eval { PRAGMA journal_mode = WAL } } + db eval { + BEGIN; + INSERT INTO t1 VALUES(NULL, randomblob(110+$E(pid))); + } + incr nRun 1 + incr nDel [file exists test.db-journal] + if {[file exists test.db-journal] + [file exists test.db-wal] != 1} { + error "File-system looks bad..." + } + db eval COMMIT + + integrity_check + db close + } + set {} "[expr $nRun-$nDel] w, $nDel r" } - set {} "[expr $nRun-$nDel] w, $nDel r" } do_thread_test walthread-3 -seconds $seconds(walthread-3) -init { diff --git a/test/where.test b/test/where.test index d4f04e8063..db0bc47a7c 100644 --- a/test/where.test +++ b/test/where.test @@ -490,12 +490,12 @@ ifcapable subquery { count { SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1; } - } {2 1 9 5} + } {2 1 9 4} do_test where-5.15 { count { SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1; } - } {2 1 9 3 1 16 9} + } {2 1 9 3 1 16 8} do_test where-5.100 { db eval { SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969) @@ -582,7 +582,7 @@ do_test where-6.7.2 { cksort { SELECT * FROM t3 WHERE b>0 ORDER BY a LIMIT 1 } -} {1 100 4 sort} +} {1 100 4 nosort} ifcapable subquery { do_test where-6.8a { cksort { @@ -1367,5 +1367,50 @@ do_execsql_test where-18.6 { SELECT DISTINCT a FROM t181 LEFT JOIN t182 ON a=b ORDER BY +a, +c IS NULL; } {1 2} +# Make sure the OR optimization works on a JOIN +# +do_execsql_test where-19.0 { + CREATE TABLE t191(a INT UNIQUE NOT NULL, b INT UNIQUE NOT NULL,c,d); + CREATE INDEX t191a ON t1(a); + CREATE INDEX t191b ON t1(b); + CREATE TABLE t192(x INTEGER PRIMARY KEY,y INT, z INT); + + EXPLAIN QUERY PLAN + SELECT t191.rowid FROM t192, t191 WHERE (a=y OR b=y) AND x=?1; +} {/.* sqlite_autoindex_t191_1 .* sqlite_autoindex_t191_2 .*/} + +# 2018-04-24 ticket [https://www.sqlite.org/src/info/4ba5abf65c5b0f9a] +# Index on expressions leads to an incorrect answer for a LEFT JOIN +# +do_execsql_test where-20.0 { + CREATE TABLE t201(x); + CREATE TABLE t202(y, z); + INSERT INTO t201 VALUES('key'); + INSERT INTO t202 VALUES('key', -1); + CREATE INDEX t202i ON t202(y, ifnull(z, 0)); + SELECT count(*) FROM t201 LEFT JOIN t202 ON (x=y) WHERE ifnull(z, 0) >=0; +} {0} + +do_execsql_test where-21.0 { + CREATE TABLE t12(a, b, c); + CREATE TABLE t13(x); + CREATE INDEX t12ab ON t12(b, a); + CREATE INDEX t12ac ON t12(c, a); + + INSERT INTO t12 VALUES(4, 0, 1); + INSERT INTO t12 VALUES(4, 1, 0); + INSERT INTO t12 VALUES(5, 0, 1); + INSERT INTO t12 VALUES(5, 1, 0); + + INSERT INTO t13 VALUES(1), (2), (3), (4); +} +do_execsql_test where-21.1 { + SELECT * FROM t12 WHERE + a = (SELECT * FROM (SELECT count(*) FROM t13 LIMIT 5) ORDER BY 1 LIMIT 10) + AND (b=1 OR c=1); +} { + 4 1 0 + 4 0 1 +} finish_test diff --git a/test/where3.test b/test/where3.test index 6edbe2bcad..4d4ea3ee68 100644 --- a/test/where3.test +++ b/test/where3.test @@ -235,17 +235,20 @@ do_execsql_test where3-3.0 { CREATE TABLE t302(x, y); INSERT INTO t302 VALUES(4,5); ANALYZE; - explain query plan SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y; -} { - 0 0 0 {SCAN TABLE t302} - 0 1 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)} } -do_execsql_test where3-3.1 { - explain query plan +do_eqp_test where3-3.0a { + SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y; +} { + QUERY PLAN + |--SCAN TABLE t302 + `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?) +} +do_eqp_test where3-3.1 { SELECT * FROM t301, t302 WHERE t302.x=5 AND t301.a=t302.y; } { - 0 0 1 {SCAN TABLE t302} - 0 1 0 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + |--SCAN TABLE t302 + `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?) } do_execsql_test where3-3.2 { SELECT * FROM t301 WHERE c=3 AND a IS NULL; @@ -308,8 +311,8 @@ do_execsql_test where3-5.0 { CREATE INDEX bbb_111 ON bbb (fk, type); CREATE INDEX bbb_222 ON bbb (parent, position); CREATE INDEX bbb_333 ON bbb (fk, lastModified); - - EXPLAIN QUERY PLAN +} +do_eqp_test where3-5.0a { SELECT bbb.title AS tag_title FROM aaa JOIN bbb ON bbb.id = aaa.parent WHERE aaa.fk = 'constant' @@ -317,12 +320,12 @@ do_execsql_test where3-5.0 { AND bbb.parent = 4 ORDER BY bbb.title COLLATE NOCASE ASC; } { - 0 0 0 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} - 0 1 1 {SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?) + |--SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?) + `--USE TEMP B-TREE FOR ORDER BY } -do_execsql_test where3-5.1 { - EXPLAIN QUERY PLAN +do_eqp_test where3-5.1 { SELECT bbb.title AS tag_title FROM aaa JOIN aaa AS bbb ON bbb.id = aaa.parent WHERE aaa.fk = 'constant' @@ -330,12 +333,12 @@ do_execsql_test where3-5.1 { AND bbb.parent = 4 ORDER BY bbb.title COLLATE NOCASE ASC; } { - 0 0 0 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} - 0 1 1 {SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?) + |--SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?) + `--USE TEMP B-TREE FOR ORDER BY } -do_execsql_test where3-5.2 { - EXPLAIN QUERY PLAN +do_eqp_test where3-5.2 { SELECT bbb.title AS tag_title FROM bbb JOIN aaa ON bbb.id = aaa.parent WHERE aaa.fk = 'constant' @@ -343,12 +346,12 @@ do_execsql_test where3-5.2 { AND bbb.parent = 4 ORDER BY bbb.title COLLATE NOCASE ASC; } { - 0 0 1 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} - 0 1 0 {SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?) + |--SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?) + `--USE TEMP B-TREE FOR ORDER BY } -do_execsql_test where3-5.3 { - EXPLAIN QUERY PLAN +do_eqp_test where3-5.3 { SELECT bbb.title AS tag_title FROM aaa AS bbb JOIN aaa ON bbb.id = aaa.parent WHERE aaa.fk = 'constant' @@ -356,9 +359,10 @@ do_execsql_test where3-5.3 { AND bbb.parent = 4 ORDER BY bbb.title COLLATE NOCASE ASC; } { - 0 0 1 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} - 0 1 0 {SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?) + |--SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?) + `--USE TEMP B-TREE FOR ORDER BY } # Name resolution with NATURAL JOIN and USING diff --git a/test/where7.test b/test/where7.test index 00cf5eb278..5abd0a8bc6 100644 --- a/test/where7.test +++ b/test/where7.test @@ -23341,8 +23341,8 @@ do_execsql_test where7-3.1 { CREATE INDEX t302_c3 on t302(c3); CREATE INDEX t302_c8_c3 on t302(c8, c3); CREATE INDEX t302_c5 on t302(c5); - - EXPLAIN QUERY PLAN +} +do_eqp_test where7-3.2 { SELECT t302.c1 FROM t302 JOIN t301 ON t302.c8 = +t301.c8 WHERE t302.c2 = 19571 @@ -23351,10 +23351,12 @@ do_execsql_test where7-3.1 { OR t301.c8 = 1407424651264000) ORDER BY t302.c5 LIMIT 200; } { - 0 0 1 {SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?)} - 0 0 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)} - 0 1 0 {SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + QUERY PLAN + |--MULTI-INDEX OR + | |--SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?) + | `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?) + |--SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?) + `--USE TEMP B-TREE FOR ORDER BY } finish_test diff --git a/test/where8.test b/test/where8.test index 38214bc895..a8dbcfd9fe 100644 --- a/test/where8.test +++ b/test/where8.test @@ -16,6 +16,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +if {[permutation]=="sorterref"} { + finish_test + return +} + # Test organization: # # where8-1.*: Tests to demonstrate simple cases work with a single table diff --git a/test/where9.test b/test/where9.test index d073074d43..87f5c15615 100644 --- a/test/where9.test +++ b/test/where9.test @@ -357,25 +357,27 @@ do_test where9-2.8 { ifcapable explain { - do_execsql_test where9-3.1 { - EXPLAIN QUERY PLAN + do_eqp_test where9-3.1 { SELECT t2.a FROM t1, t2 WHERE t1.a=80 AND ((t1.c=t2.c AND t1.d=t2.d) OR t1.f=t2.f) - } { - 0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)} - 0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?)} - 0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)} - } - do_execsql_test where9-3.2 { - EXPLAIN QUERY PLAN + } [string map {"\n " \n} { + QUERY PLAN + |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) + `--MULTI-INDEX OR + |--SEARCH TABLE t2 USING INDEX t2d (d=?) + `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) + }] + do_eqp_test where9-3.2 { SELECT coalesce(t2.a,9999) FROM t1 LEFT JOIN t2 ON (t1.c+1=t2.c AND t1.d=t2.d) OR (t1.f||'x')=t2.f WHERE t1.a=80 - } { - 0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)} - 0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?)} - 0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)} - } + } [string map {"\n " \n} { + QUERY PLAN + |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) + `--MULTI-INDEX OR + |--SEARCH TABLE t2 USING INDEX t2d (d=?) + `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) + }] } # Make sure that INDEXED BY and multi-index OR clauses play well with @@ -446,35 +448,31 @@ do_test where9-4.8 { } } {1 {no query solution}} -ifcapable explain { - # The (c=31031 OR d IS NULL) clause is preferred over b>1000 because - # the former is an equality test which is expected to return fewer rows. - # - do_execsql_test where9-5.1 { - EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL) - } { - 0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?)} - 0 0 0 {SEARCH TABLE t1 USING INDEX t1d (d=?)} - } - - # In contrast, b=1000 is preferred over any OR-clause. - # - do_execsql_test where9-5.2 { - EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL) - } { - 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)} - } - - # Likewise, inequalities in an AND are preferred over inequalities in - # an OR. - # - do_execsql_test where9-5.3 { - EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c>=31031 OR d IS NULL) - } { - 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>?)} - } +# The (c=31031 OR d IS NULL) clause is preferred over b>1000 because +# the former is an equality test which is expected to return fewer rows. +# +do_eqp_test where9-5.1 { + SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL) +} { + QUERY PLAN + `--MULTI-INDEX OR + |--SEARCH TABLE t1 USING INDEX t1c (c=?) + `--SEARCH TABLE t1 USING INDEX t1d (d=?) } +# In contrast, b=1000 is preferred over any OR-clause. +# +do_eqp_test where9-5.2 { + SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL) +} {SEARCH TABLE t1 USING INDEX t1b (b=?)} + +# Likewise, inequalities in an AND are preferred over inequalities in +# an OR. +# +do_eqp_test where9-5.3 { + SELECT a FROM t1 WHERE b>1000 AND (c>=31031 OR d IS NULL) +} {SEARCH TABLE t1 USING INDEX t1b (b>?)} + ############################################################################ # Make sure OR-clauses work correctly on UPDATE and DELETE statements. diff --git a/test/whereF.test b/test/whereF.test index 3b938aa203..121cc3cf22 100644 --- a/test/whereF.test +++ b/test/whereF.test @@ -176,4 +176,137 @@ do_execsql_test 5.5 { } {4} do_test 5.6 { expr [db status vmstep]<200 } 1 +# 2017-09-04 ticket b899b6042f97f52d +# Segfault on correlated subquery... +# +ifcapable json1&&vtab { + do_execsql_test 6.1 { + CREATE TABLE t6(x); + SELECT * FROM t6 WHERE 1 IN (SELECT value FROM json_each(x)); + } {} + + do_execsql_test 6.2 { + DROP TABLE t6; + CREATE TABLE t6(a,b,c); + INSERT INTO t6 VALUES + (0,null,'{"a":0,"b":[3,4,5],"c":{"x":4.5,"y":7.8}}'), + (1,null,'{"a":1,"b":[3,4,5],"c":{"x":4.5,"y":7.8}}'), + (2,null,'{"a":9,"b":[3,4,5],"c":{"x":4.5,"y":7.8}}'); + SELECT * FROM t6 + WHERE (EXISTS (SELECT 1 FROM json_each(t6.c) AS x WHERE x.value=1)); + } {1 {} {{"a":1,"b":[3,4,5],"c":{"x":4.5,"y":7.8}}}} + + # Another test case derived from a posting by Wout Mertens on the + # sqlite-users mailing list on 2017-10-04. + do_execsql_test 6.3 { + DROP TABLE IF EXISTS t; + CREATE TABLE t(json JSON); + SELECT * FROM t + WHERE(EXISTS(SELECT 1 FROM json_each(t.json,"$.foo") j + WHERE j.value = 'meep')); + } {} + do_execsql_test 6.4 { + INSERT INTO t VALUES('{"xyzzy":null}'); + INSERT INTO t VALUES('{"foo":"meep","other":12345}'); + INSERT INTO t VALUES('{"foo":"bingo","alt":5.25}'); + SELECT * FROM t + WHERE(EXISTS(SELECT 1 FROM json_each(t.json,"$.foo") j + WHERE j.value = 'meep')); + } {{{"foo":"meep","other":12345}}} +} + +# 2018-01-27 +# Ticket https://sqlite.org/src/tktview/ec32177c99ccac2b180fd3ea2083 +# Incorrect result when using the new OR clause factoring optimization +# +# This is the original test case as reported on the sqlite-users mailing +# list +# +do_execsql_test 7.1 { + DROP TABLE IF EXISTS cd; + CREATE TABLE cd ( cdid INTEGER PRIMARY KEY NOT NULL, genreid integer ); + CREATE INDEX cd_idx_genreid ON cd (genreid); + INSERT INTO cd ( cdid, genreid ) VALUES + ( 1, 1 ), + ( 2, NULL ), + ( 3, NULL ), + ( 4, NULL ), + ( 5, NULL ); + + SELECT cdid + FROM cd me + WHERE 2 > ( + SELECT COUNT( * ) + FROM cd rownum__emulation + WHERE + ( + me.genreid IS NOT NULL + AND + rownum__emulation.genreid IS NULL + ) + OR + ( + me.genreid IS NOT NULL + AND + rownum__emulation.genreid IS NOT NULL + AND + rownum__emulation.genreid < me.genreid + ) + OR + ( + ( me.genreid = rownum__emulation.genreid OR ( me.genreid IS NULL + AND rownum__emulation.genreid IS NULL ) ) + AND + rownum__emulation.cdid > me.cdid + ) + ); +} {4 5} + +# Simplified test cases from the ticket +# +do_execsql_test 7.2 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1(a,b) VALUES(1,1); + CREATE TABLE t2(aa INTEGER PRIMARY KEY, bb); + INSERT INTO t2(aa,bb) VALUES(1,1),(2,NULL),(3,NULL); + SELECT ( + SELECT COUNT(*) FROM t2 + WHERE ( t1.b IS NOT NULL AND t2.bb IS NULL ) + OR ( t2.bb < t1.b ) + OR ( t1.b IS t2.bb AND t2.aa > t1.a ) + ) + FROM t1; +} {2} + +# The fix for ticket ec32177c99ccac2b180fd3ea2083 only makes a difference +# in the output when there is a TERM_VNULL entry in the WhereClause array. +# And TERM_VNULL entries are only generated when compiling with +# SQLITE_ENABLE_STAT4. Nevertheless, it is correct that TERM_VIRTUAL terms +# should not participate in the factoring optimization. In all cases other +# than TERM_VNULL, participation is harmless, but it does consume a few +# extra CPU cycles. +# +# The following test verifies that the TERM_VIRTUAL terms resulting from +# a GLOB operator do not appear anywhere in the generated code. This +# confirms that the problem is fixed, even on builds that omit STAT4. +# +do_execsql_test 7.3 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT); + INSERT INTO t1(a,b) VALUES(1,'abcxyz'); + CREATE TABLE t2(aa INTEGER PRIMARY KEY, bb TEXT); + INSERT INTO t2(aa,bb) VALUES(1,'abc'),(2,'wxyz'),(3,'xyz'); + CREATE INDEX t2bb ON t2(bb); + EXPLAIN SELECT ( + SELECT COUNT(*) FROM t2 + WHERE ( t1.b GLOB 'a*z' AND t2.bb='xyz' ) + OR ( t2.bb = t1.b ) + OR ( t2.aa = t1.a ) + ) + FROM t1; +} {~/ (Lt|Ge) /} + finish_test diff --git a/test/whereG.test b/test/whereG.test index 110ed5dbd4..d2e6a4ee96 100644 --- a/test/whereG.test +++ b/test/whereG.test @@ -66,7 +66,7 @@ do_eqp_test whereG-1.1 { WHERE unlikely(cname LIKE '%bach%') AND composer.cid=track.cid AND album.aid=track.aid; -} {/.*composer.*track.*album.*/} +} {composer*track*album} do_execsql_test whereG-1.2 { SELECT DISTINCT aname FROM album, composer, track @@ -195,13 +195,13 @@ do_execsql_test 5.1 { } do_eqp_test 5.1.2 { SELECT * FROM t1 WHERE a>? -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}} +} {SEARCH TABLE t1 USING INDEX i1 (a>?)} do_eqp_test 5.1.3 { SELECT * FROM t1 WHERE likelihood(a>?, 0.9) -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} do_eqp_test 5.1.4 { SELECT * FROM t1 WHERE likely(a>?) -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} do_test 5.2 { for {set i 0} {$i < 100} {incr i} { @@ -212,23 +212,23 @@ do_test 5.2 { } {} do_eqp_test 5.2.2 { SELECT * FROM t1 WHERE likelihood(b>?, 0.01) -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (ANY(a) AND b>?)}} +} {SEARCH TABLE t1 USING INDEX i1 (ANY(a) AND b>?)} do_eqp_test 5.2.3 { SELECT * FROM t1 WHERE likelihood(b>?, 0.9) -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} do_eqp_test 5.2.4 { SELECT * FROM t1 WHERE likely(b>?) -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} do_eqp_test 5.3.1 { SELECT * FROM t1 WHERE a=? -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}} +} {SEARCH TABLE t1 USING INDEX i1 (a=?)} do_eqp_test 5.3.2 { SELECT * FROM t1 WHERE likelihood(a=?, 0.9) -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} do_eqp_test 5.3.3 { SELECT * FROM t1 WHERE likely(a=?) -} {0 0 0 {SCAN TABLE t1}} +} {SCAN TABLE t1} # 2015-06-18 # Ticket [https://www.sqlite.org/see/tktview/472f0742a1868fb58862bc588ed70] diff --git a/test/whereI.test b/test/whereI.test index 29b08549be..d08e62c376 100644 --- a/test/whereI.test +++ b/test/whereI.test @@ -29,8 +29,10 @@ do_execsql_test 1.0 { do_eqp_test 1.1 { SELECT a FROM t1 WHERE b='b' OR c='x' } { - 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b=?)} - 0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)} + QUERY PLAN + `--MULTI-INDEX OR + |--SEARCH TABLE t1 USING INDEX i1 (b=?) + `--SEARCH TABLE t1 USING INDEX i2 (c=?) } do_execsql_test 1.2 { @@ -57,8 +59,10 @@ do_execsql_test 2.0 { do_eqp_test 2.1 { SELECT a FROM t2 WHERE b='b' OR c='x' } { - 0 0 0 {SEARCH TABLE t2 USING INDEX i3 (b=?)} - 0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?)} + QUERY PLAN + `--MULTI-INDEX OR + |--SEARCH TABLE t2 USING INDEX i3 (b=?) + `--SEARCH TABLE t2 USING INDEX i4 (c=?) } do_execsql_test 2.2 { diff --git a/test/whereJ.test b/test/whereJ.test index 48924d0fcf..af6ffafb3f 100644 --- a/test/whereJ.test +++ b/test/whereJ.test @@ -402,9 +402,7 @@ do_eqp_test 3.4 { a = 4 AND b BETWEEN 20 AND 80 -- Matches 80 rows AND c BETWEEN 150 AND 160 -- Matches 10 rows -} { - 0 0 0 {SEARCH TABLE t1 USING INDEX idx_c (c>? AND c? AND c? AND b? AND b0) OVER (PARTITION BY d ORDER BY c) FROM t1" + 6 "SELECT sum(b) OVER (ORDER BY c RANGE UNBOUNDED PRECEDING) FROM t1" + 7 "SELECT sum(b) OVER (ORDER BY c ROWS 45 PRECEDING) FROM t1" + 8 "SELECT sum(b) OVER (ORDER BY c RANGE CURRENT ROW) FROM t1" + 9 "SELECT sum(b) OVER (ORDER BY c RANGE BETWEEN UNBOUNDED PRECEDING + AND CURRENT ROW) FROM t1" + 10 "SELECT sum(b) OVER (ORDER BY c ROWS BETWEEN UNBOUNDED PRECEDING + AND UNBOUNDED FOLLOWING) FROM t1" +} { + do_test 2.$tn { lindex [catchsql $sql] 0 } 0 +} + +foreach {tn sql} { + 1 "SELECT * FROM t1 WHERE sum(b) OVER ()" + 2 "SELECT * FROM t1 GROUP BY sum(b) OVER ()" + 3 "SELECT * FROM t1 GROUP BY a HAVING sum(b) OVER ()" +} { + do_catchsql_test 3.$tn $sql {1 {misuse of window function sum()}} +} + +do_execsql_test 4.0 { + CREATE TABLE t2(a, b, c); + INSERT INTO t2 VALUES(0, 0, 0); + INSERT INTO t2 VALUES(1, 1, 1); + INSERT INTO t2 VALUES(2, 0, 2); + INSERT INTO t2 VALUES(3, 1, 0); + INSERT INTO t2 VALUES(4, 0, 1); + INSERT INTO t2 VALUES(5, 1, 2); + INSERT INTO t2 VALUES(6, 0, 0); +} + +do_execsql_test 4.1 { + SELECT a, sum(a) OVER (PARTITION BY b) FROM t2; +} { + 0 12 2 12 4 12 6 12 1 9 3 9 5 9 +} + +do_execsql_test 4.2 { + SELECT a, sum(a) OVER (PARTITION BY b) FROM t2 ORDER BY a; +} { + 0 12 1 9 2 12 3 9 4 12 5 9 6 12 +} + +do_execsql_test 4.3 { + SELECT a, sum(a) OVER () FROM t2 ORDER BY a; +} { + 0 21 1 21 2 21 3 21 4 21 5 21 6 21 +} + +do_execsql_test 4.4 { + SELECT a, sum(a) OVER (ORDER BY a) FROM t2; +} { + 0 0 1 1 2 3 3 6 4 10 5 15 6 21 +} + +do_execsql_test 4.5 { + SELECT a, sum(a) OVER (PARTITION BY b ORDER BY a) FROM t2 ORDER BY a +} { + 0 0 1 1 2 2 3 4 4 6 5 9 6 12 +} + +do_execsql_test 4.6 { + SELECT a, sum(a) OVER (PARTITION BY c ORDER BY a) FROM t2 ORDER BY a +} { + 0 0 1 1 2 2 3 3 4 5 5 7 6 9 +} + +do_execsql_test 4.7 { + SELECT a, sum(a) OVER (PARTITION BY b ORDER BY a DESC) FROM t2 ORDER BY a +} { + 0 12 1 9 2 12 3 8 4 10 5 5 6 6 +} + +do_execsql_test 4.8 { + SELECT a, + sum(a) OVER (PARTITION BY b ORDER BY a DESC), + sum(a) OVER (PARTITION BY c ORDER BY a) + FROM t2 ORDER BY a +} { + 0 12 0 + 1 9 1 + 2 12 2 + 3 8 3 + 4 10 5 + 5 5 7 + 6 6 9 +} + +do_execsql_test 4.9 { + SELECT a, + sum(a) OVER (ORDER BY a), + avg(a) OVER (ORDER BY a) + FROM t2 ORDER BY a +} { + 0 0 0.0 + 1 1 0.5 + 2 3 1.0 + 3 6 1.5 + 4 10 2.0 + 5 15 2.5 + 6 21 3.0 +} + +do_execsql_test 4.10.1 { + SELECT a, + count() OVER (ORDER BY a DESC), + group_concat(a, '.') OVER (ORDER BY a DESC) + FROM t2 ORDER BY a DESC +} { + 6 1 6 + 5 2 6.5 + 4 3 6.5.4 + 3 4 6.5.4.3 + 2 5 6.5.4.3.2 + 1 6 6.5.4.3.2.1 + 0 7 6.5.4.3.2.1.0 +} + +do_execsql_test 4.10.2 { + SELECT a, + count(*) OVER (ORDER BY a DESC), + group_concat(a, '.') OVER (ORDER BY a DESC) + FROM t2 ORDER BY a DESC +} { + 6 1 6 + 5 2 6.5 + 4 3 6.5.4 + 3 4 6.5.4.3 + 2 5 6.5.4.3.2 + 1 6 6.5.4.3.2.1 + 0 7 6.5.4.3.2.1.0 +} + +do_catchsql_test 5.1 { + SELECT ntile(0) OVER (ORDER BY a) FROM t2; +} {1 {argument of ntile must be a positive integer}} +do_catchsql_test 5.2 { + SELECT ntile(-1) OVER (ORDER BY a) FROM t2; +} {1 {argument of ntile must be a positive integer}} +do_catchsql_test 5.3 { + SELECT ntile('zbc') OVER (ORDER BY a) FROM t2; +} {1 {argument of ntile must be a positive integer}} +do_execsql_test 5.4 { + CREATE TABLE t4(a, b); + SELECT ntile(1) OVER (ORDER BY a) FROM t4; +} {} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.1 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(7), (6), (5), (4), (3), (2), (1); + + CREATE TABLE t2(x); + INSERT INTO t2 VALUES('b'), ('a'); + + SELECT x, count(*) OVER (ORDER BY x) FROM t1; +} {1 1 2 2 3 3 4 4 5 5 6 6 7 7} + +do_execsql_test 6.2 { + SELECT * FROM t2, (SELECT x, count(*) OVER (ORDER BY x) FROM t1); +} { + b 1 1 b 2 2 b 3 3 b 4 4 b 5 5 b 6 6 b 7 7 + a 1 1 a 2 2 a 3 3 a 4 4 a 5 5 a 6 6 a 7 7 +} + +do_catchsql_test 6.3 { + SELECT x, lag(x) FILTER (WHERE (x%2)=0) OVER w FROM t1 + WINDOW w AS (ORDER BY x) +} {1 {FILTER clause may only be used with aggregate window functions}} + +#------------------------------------------------------------------------- +# Attempt to use a window function as an aggregate. And other errors. +# +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + INSERT INTO t1 VALUES(9, 10); +} + +do_catchsql_test 7.1.1 { + SELECT nth_value(x, 1) FROM t1; +} {1 {misuse of window function nth_value()}} +do_catchsql_test 7.1.2 { + SELECT * FROM t1 WHERE nth_value(x, 1) OVER (ORDER BY y); +} {1 {misuse of window function nth_value()}} +do_catchsql_test 7.1.3 { + SELECT count(*) FROM t1 GROUP BY y HAVING nth_value(x, 1) OVER (ORDER BY y); +} {1 {misuse of window function nth_value()}} +do_catchsql_test 7.1.4 { + SELECT count(*) FROM t1 GROUP BY nth_value(x, 1) OVER (ORDER BY y); +} {1 {misuse of window function nth_value()}} +do_catchsql_test 7.1.5 { + SELECT count(*) FROM t1 LIMIT nth_value(x, 1) OVER (); +} {1 {no such column: x}} +do_catchsql_test 7.1.6 { + SELECT trim(x) OVER (ORDER BY y) FROM t1; +} {1 {trim() may not be used as a window function}} +do_catchsql_test 7.1.7 { + SELECT max(x) OVER abc FROM t1 WINDOW def AS (ORDER BY y); +} {1 {no such window: abc}} + +do_execsql_test 7.2 { + SELECT + lead(y) OVER win, + lead(y, 2) OVER win, + lead(y, 3, 'default') OVER win + FROM t1 + WINDOW win AS (ORDER BY x) +} { + 4 6 8 6 8 10 8 10 default 10 {} default {} {} default +} + +do_execsql_test 7.3 { + SELECT row_number() OVER (ORDER BY x) FROM t1 +} {1 2 3 4 5} + +do_execsql_test 7.4 { + SELECT + row_number() OVER win, + lead(x) OVER win + FROM t1 + WINDOW win AS (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {1 3 2 5 3 7 4 9 5 {}} + +#------------------------------------------------------------------------- +# Attempt to use a window function in a view. +# +do_execsql_test 8.0 { + CREATE TABLE t3(a, b, c); + + WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<6 ) + INSERT INTO t3 SELECT i, i, i FROM s; + + CREATE VIEW v1 AS SELECT + sum(b) OVER (ORDER BY c), + min(b) OVER (ORDER BY c), + max(b) OVER (ORDER BY c) + FROM t3; + + CREATE VIEW v2 AS SELECT + sum(b) OVER win, + min(b) OVER win, + max(b) OVER win + FROM t3 + WINDOW win AS (ORDER BY c); +} + +do_execsql_test 8.1.1 { + SELECT * FROM v1 +} {1 1 1 3 1 2 6 1 3 10 1 4 15 1 5 21 1 6} +do_execsql_test 8.1.2 { + SELECT * FROM v2 +} {1 1 1 3 1 2 6 1 3 10 1 4 15 1 5 21 1 6} + +db close +sqlite3 db test.db +do_execsql_test 8.2.1 { + SELECT * FROM v1 +} {1 1 1 3 1 2 6 1 3 10 1 4 15 1 5 21 1 6} +do_execsql_test 8.2.2 { + SELECT * FROM v2 +} {1 1 1 3 1 2 6 1 3 10 1 4 15 1 5 21 1 6} + +#------------------------------------------------------------------------- +# Attempt to use a window function in a trigger. +# +do_execsql_test 9.0 { + CREATE TABLE t4(x, y); + INSERT INTO t4 VALUES(1, 'g'); + INSERT INTO t4 VALUES(2, 'i'); + INSERT INTO t4 VALUES(3, 'l'); + INSERT INTO t4 VALUES(4, 'g'); + INSERT INTO t4 VALUES(5, 'a'); + + CREATE TABLE t5(x, y, m); + CREATE TRIGGER t4i AFTER INSERT ON t4 BEGIN + DELETE FROM t5; + INSERT INTO t5 + SELECT x, y, max(y) OVER xyz FROM t4 + WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x); + END; +} + +do_execsql_test 9.1.1 { + SELECT x, y, max(y) OVER xyz FROM t4 + WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x) ORDER BY 1 +} {1 g g 2 i i 3 l l 4 g i 5 a l} + +do_execsql_test 9.1.2 { + INSERT INTO t4 VALUES(6, 'm'); + SELECT x, y, max(y) OVER xyz FROM t4 + WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x) ORDER BY 1 +} {1 g g 2 i i 3 l l 4 g i 5 a l 6 m m} + +do_execsql_test 9.1.3 { + SELECT * FROM t5 ORDER BY 1 +} {1 g g 2 i i 3 l l 4 g i 5 a l 6 m m} + +do_execsql_test 9.2 { + WITH aaa(x, y, z) AS ( + SELECT x, y, max(y) OVER xyz FROM t4 + WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x) + ) + SELECT * FROM aaa ORDER BY 1; +} {1 g g 2 i i 3 l l 4 g i 5 a l 6 m m} + +do_execsql_test 9.3 { + WITH aaa(x, y, z) AS ( + SELECT x, y, max(y) OVER xyz FROM t4 + WINDOW xyz AS (ORDER BY x) + ) + SELECT *, min(z) OVER (ORDER BY x) FROM aaa ORDER BY 1; +} {1 g g g 2 i i g 3 l l g 4 g l g 5 a l g 6 m m g} + +#------------------------------------------------------------------------- +# +do_execsql_test 10.0 { + CREATE TABLE sales(emp TEXT PRIMARY KEY, region, total); + INSERT INTO sales VALUES + ('Alice', 'North', 34), + ('Frank', 'South', 22), + ('Charles', 'North', 45), + ('Darrell', 'South', 8), + ('Grant', 'South', 23), + ('Brad' , 'North', 22), + ('Elizabeth', 'South', 99), + ('Horace', 'East', 1); +} + +# Best two salespeople from each region +# +do_execsql_test 10.1 { + SELECT emp, region, total FROM ( + SELECT + emp, region, total, + row_number() OVER (PARTITION BY region ORDER BY total DESC) AS rank + FROM sales + ) WHERE rank<=2 ORDER BY region, total DESC +} { + Horace East 1 + Charles North 45 + Alice North 34 + Elizabeth South 99 + Grant South 23 +} + +do_execsql_test 10.2 { + SELECT emp, region, sum(total) OVER win FROM sales + WINDOW win AS (PARTITION BY region ORDER BY total) +} { + Horace East 1 + Brad North 22 + Alice North 56 + Charles North 101 + Darrell South 8 + Frank South 30 + Grant South 53 + Elizabeth South 152 +} + +do_execsql_test 10.3 { + SELECT emp, region, sum(total) OVER win FROM sales + WINDOW win AS (PARTITION BY region ORDER BY total) + LIMIT 5 +} { + Horace East 1 + Brad North 22 + Alice North 56 + Charles North 101 + Darrell South 8 +} + +do_execsql_test 10.4 { + SELECT emp, region, sum(total) OVER win FROM sales + WINDOW win AS (PARTITION BY region ORDER BY total) + LIMIT 5 OFFSET 2 +} { + Alice North 56 + Charles North 101 + Darrell South 8 + Frank South 30 + Grant South 53 +} + +do_execsql_test 10.5 { + SELECT emp, region, sum(total) OVER win FROM sales + WINDOW win AS ( + PARTITION BY region ORDER BY total + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) +} { + Horace East 1 + Brad North 101 + Alice North 79 + Charles North 45 + Darrell South 152 + Frank South 144 + Grant South 122 + Elizabeth South 99 +} + +do_execsql_test 10.6 { + SELECT emp, region, sum(total) OVER win FROM sales + WINDOW win AS ( + PARTITION BY region ORDER BY total + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) LIMIT 5 OFFSET 2 +} { + Alice North 79 + Charles North 45 + Darrell South 152 + Frank South 144 + Grant South 122 +} + +do_execsql_test 10.7 { + SELECT emp, region, ( + SELECT sum(total) OVER ( + ORDER BY total RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) || outer.emp FROM sales + ) FROM sales AS outer; +} { + Alice North 254Alice + Frank South 254Frank + Charles North 254Charles + Darrell South 254Darrell + Grant South 254Grant + Brad North 254Brad + Elizabeth South 254Elizabeth + Horace East 254Horace +} + +do_execsql_test 10.8 { + SELECT emp, region, ( + SELECT sum(total) FILTER (WHERE sales.emp!=outer.emp) OVER ( + ORDER BY total RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM sales + ) FROM sales AS outer; +} { + Alice North 220 + Frank South 232 + Charles North 209 + Darrell South 246 + Grant South 231 + Brad North 232 + Elizabeth South 155 + Horace East 253 +} + +#------------------------------------------------------------------------- +# Check that it is not possible to use a window function in a CREATE INDEX +# statement. +# +do_execsql_test 11.0 { CREATE TABLE t6(a, b, c); } + +do_catchsql_test 11.1 { + CREATE INDEX t6i ON t6(a) WHERE sum(b) OVER (); +} {1 {misuse of window function sum()}} +do_catchsql_test 11.2 { + CREATE INDEX t6i ON t6(a) WHERE lead(b) OVER (); +} {1 {misuse of window function lead()}} + +do_catchsql_test 11.3 { + CREATE INDEX t6i ON t6(sum(b) OVER ()); +} {1 {misuse of window function sum()}} +do_catchsql_test 11.4 { + CREATE INDEX t6i ON t6(lead(b) OVER ()); +} {1 {misuse of window function lead()}} + +# 2018-09-17 ticket 510cde277783b5fb5de628393959849dff377eb3 +# Endless loop on a query with window functions and a limit +# +do_execsql_test 12.100 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(id INT, b VARCHAR, c VARCHAR); + INSERT INTO t1 VALUES(1, 'A', 'one'); + INSERT INTO t1 VALUES(2, 'B', 'two'); + INSERT INTO t1 VALUES(3, 'C', 'three'); + INSERT INTO t1 VALUES(4, 'D', 'one'); + INSERT INTO t1 VALUES(5, 'E', 'two'); + SELECT id, b, lead(c,1) OVER(ORDER BY c) AS x + FROM t1 WHERE id>1 + ORDER BY b LIMIT 1; +} {2 B two} +do_execsql_test 12.110 { + INSERT INTO t1 VALUES(6, 'F', 'three'); + INSERT INTO t1 VALUES(7, 'G', 'one'); + SELECT id, b, lead(c,1) OVER(ORDER BY c) AS x + FROM t1 WHERE id>1 + ORDER BY b LIMIT 2; +} {2 B two 3 C three} + +finish_test diff --git a/test/window2.tcl b/test/window2.tcl new file mode 100644 index 0000000000..48fcdaea40 --- /dev/null +++ b/test/window2.tcl @@ -0,0 +1,424 @@ +# 2018 May 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname $argv0] pg_common.tcl] + +#========================================================================= + + +start_test window2 "2018 May 19" + +ifcapable !windowfunc + +execsql_test 1.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER); + INSERT INTO t1 VALUES(1, 'odd', 'one', 1); + INSERT INTO t1 VALUES(2, 'even', 'two', 2); + INSERT INTO t1 VALUES(3, 'odd', 'three', 3); + INSERT INTO t1 VALUES(4, 'even', 'four', 4); + INSERT INTO t1 VALUES(5, 'odd', 'five', 5); + INSERT INTO t1 VALUES(6, 'even', 'six', 6); +} + +execsql_test 1.1 { + SELECT c, sum(d) OVER (PARTITION BY b ORDER BY c) FROM t1; +} + +execsql_test 1.2 { + SELECT sum(d) OVER () FROM t1; +} + +execsql_test 1.3 { + SELECT sum(d) OVER (PARTITION BY b) FROM t1; +} + +========== +execsql_test 2.1 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1000 PRECEDING AND 1 FOLLOWING + ) FROM t1 +} +execsql_test 2.2 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1000 PRECEDING AND 1000 FOLLOWING + ) FROM t1 +} +execsql_test 2.3 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1000 FOLLOWING + ) FROM t1 +} +execsql_test 2.4 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 +} +execsql_test 2.5 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING + ) FROM t1 +} + +execsql_test 2.6 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 +} + +execsql_test 2.7 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING + ) FROM t1 +} + +execsql_test 2.8 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING + ) FROM t1 +} + +execsql_test 2.9 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING + ) FROM t1 +} + +execsql_test 2.10 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING + ) FROM t1 +} + +execsql_test 2.11 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 2 PRECEDING AND CURRENT ROW + ) FROM t1 +} + +execsql_test 2.13 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 2.14 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING + ) FROM t1 +} + +execsql_test 2.15 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING + ) FROM t1 +} + +execsql_test 2.16 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING + ) FROM t1 +} + +execsql_test 2.17 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING + ) FROM t1 +} + +execsql_test 2.18 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND 2 PRECEDING + ) FROM t1 +} + +execsql_test 2.19 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING + ) FROM t1 +} + +execsql_test 2.20 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING + ) FROM t1 +} + +execsql_test 2.21 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 2.22 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 2.23 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 2.24 { + SELECT a, sum(d) OVER ( + PARTITION BY a%2 + ORDER BY d + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 2.25 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 2.26 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 2.27 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t1 +} + +execsql_test 2.28 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t1 +} + +execsql_test 2.29 { + SELECT a, sum(d) OVER ( + ORDER BY d + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} +execsql_test 2.30 { + SELECT a, sum(d) OVER ( + ORDER BY b + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 3.1 { + SELECT a, sum(d) OVER ( + PARTITION BY b ORDER BY d + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 3.2 { + SELECT a, sum(d) OVER ( + ORDER BY b + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 3.3 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} + +execsql_test 3.4 { + SELECT a, sum(d) OVER ( + ORDER BY d/2 + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t1 +} + +#puts $::fd finish_test + +========== + +execsql_test 4.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t2(a, b) VALUES + (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2), + (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62), + (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78), + (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77), + (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7), + (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43), + (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90), + (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56), + (66,40), (67,43), (68,56), (69,16), (70,75), (71,36), (72,89), (73,98), + (74,76), (75,81), (76,4), (77,94), (78,42), (79,30), (80,78), (81,33), + (82,29), (83,53), (84,63), (85,2), (86,87), (87,37), (88,80), (89,84), + (90,72), (91,41), (92,9), (93,61), (94,73), (95,95), (96,65), (97,13), + (98,58), (99,96), (100,98), (101,1), (102,21), (103,74), (104,65), (105,35), + (106,5), (107,73), (108,11), (109,51), (110,87), (111,41), (112,12), (113,8), + (114,20), (115,31), (116,31), (117,15), (118,95), (119,22), (120,73), + (121,79), (122,88), (123,34), (124,8), (125,11), (126,49), (127,34), + (128,90), (129,59), (130,96), (131,60), (132,55), (133,75), (134,77), + (135,44), (136,2), (137,7), (138,85), (139,57), (140,74), (141,29), (142,70), + (143,59), (144,19), (145,39), (146,26), (147,26), (148,47), (149,80), + (150,90), (151,36), (152,58), (153,47), (154,9), (155,72), (156,72), (157,66), + (158,33), (159,93), (160,75), (161,64), (162,81), (163,9), (164,23), (165,37), + (166,13), (167,12), (168,14), (169,62), (170,91), (171,36), (172,91), + (173,33), (174,15), (175,34), (176,36), (177,99), (178,3), (179,95), (180,69), + (181,58), (182,52), (183,30), (184,50), (185,84), (186,10), (187,84), + (188,33), (189,21), (190,39), (191,44), (192,58), (193,30), (194,38), + (195,34), (196,83), (197,27), (198,82), (199,17), (200,7); +} + +execsql_test 4.1 { + SELECT a, sum(b) OVER ( + PARTITION BY (b%10) + ORDER BY b + ) FROM t2 ORDER BY a; +} + +execsql_test 4.2 { + SELECT a, sum(b) OVER ( + PARTITION BY (b%10) + ORDER BY b + RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY a; +} + +execsql_test 4.3 { + SELECT b, sum(b) OVER ( + ORDER BY b + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY b; +} + +execsql_test 4.4 { + SELECT b, sum(b) OVER ( + ORDER BY b + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY b; +} + +execsql_test 4.5 { + SELECT b, sum(b) OVER ( + ORDER BY b + RANGE BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY b; +} + +execsql_test 4.6.1 { + SELECT b, sum(b) OVER ( + RANGE BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY b; +} +execsql_test 4.6.2 { + SELECT b, sum(b) OVER () FROM t2 ORDER BY b; +} +execsql_test 4.6.3 { + SELECT b, sum(b) OVER ( + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY b; +} +execsql_test 4.6.4 { + SELECT b, sum(b) OVER ( + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY b; +} + +execsql_test 4.7.1 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} +execsql_test 4.7.2 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} +execsql_test 4.7.3 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} +execsql_test 4.7.4 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} + +execsql_test 4.8.1 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} +execsql_test 4.8.2 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} +execsql_test 4.8.3 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} +execsql_test 4.8.4 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} + + + +finish_test + + diff --git a/test/window2.test b/test/window2.test new file mode 100644 index 0000000000..086e56603d --- /dev/null +++ b/test/window2.test @@ -0,0 +1,434 @@ +# 2018 May 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +#################################################### +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! +#################################################### + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix window2 + +ifcapable !windowfunc { finish_test ; return } +do_execsql_test 1.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER); + INSERT INTO t1 VALUES(1, 'odd', 'one', 1); + INSERT INTO t1 VALUES(2, 'even', 'two', 2); + INSERT INTO t1 VALUES(3, 'odd', 'three', 3); + INSERT INTO t1 VALUES(4, 'even', 'four', 4); + INSERT INTO t1 VALUES(5, 'odd', 'five', 5); + INSERT INTO t1 VALUES(6, 'even', 'six', 6); +} {} + +do_execsql_test 1.1 { + SELECT c, sum(d) OVER (PARTITION BY b ORDER BY c) FROM t1; +} {four 4 six 10 two 12 five 5 one 6 three 9} + +do_execsql_test 1.2 { + SELECT sum(d) OVER () FROM t1; +} {21 21 21 21 21 21} + +do_execsql_test 1.3 { + SELECT sum(d) OVER (PARTITION BY b) FROM t1; +} {12 12 12 9 9 9} + +#========================================================================== + +do_execsql_test 2.1 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1000 PRECEDING AND 1 FOLLOWING + ) FROM t1 +} {1 3 2 6 3 10 4 15 5 21 6 21} + +do_execsql_test 2.2 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1000 PRECEDING AND 1000 FOLLOWING + ) FROM t1 +} {1 21 2 21 3 21 4 21 5 21 6 21} + +do_execsql_test 2.3 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1000 FOLLOWING + ) FROM t1 +} {1 21 2 21 3 20 4 18 5 15 6 11} + +do_execsql_test 2.4 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 +} {1 3 2 6 3 9 4 12 5 15 6 11} + +do_execsql_test 2.5 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING + ) FROM t1 +} {1 1 2 3 3 5 4 7 5 9 6 11} + +do_execsql_test 2.6 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 +} {2 6 4 12 6 10 1 4 3 9 5 8} + +do_execsql_test 2.7 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING + ) FROM t1 +} {2 2 4 4 6 6 1 1 3 3 5 5} + +do_execsql_test 2.8 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING + ) FROM t1 +} {1 6 2 9 3 12 4 15 5 11 6 6} + +do_execsql_test 2.9 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING + ) FROM t1 +} {1 6 2 10 3 15 4 21 5 21 6 21} + +do_execsql_test 2.10 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING + ) FROM t1 +} {1 6 2 9 3 12 4 15 5 11 6 6} + +do_execsql_test 2.11 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 2 PRECEDING AND CURRENT ROW + ) FROM t1 +} {1 1 2 3 3 6 4 9 5 12 6 15} + +do_execsql_test 2.13 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} {1 21 2 21 3 21 4 20 5 18 6 15} + +do_execsql_test 2.14 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING + ) FROM t1 +} {1 {} 2 1 3 3 4 6 5 9 6 12} + +do_execsql_test 2.15 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING + ) FROM t1 +} {2 2 4 6 6 10 1 1 3 4 5 8} + +do_execsql_test 2.16 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING + ) FROM t1 +} {2 {} 4 2 6 4 1 {} 3 1 5 3} + +do_execsql_test 2.17 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING + ) FROM t1 +} {2 {} 4 {} 6 {} 1 {} 3 {} 5 {}} + +do_execsql_test 2.18 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND 2 PRECEDING + ) FROM t1 +} {2 {} 4 {} 6 2 1 {} 3 {} 5 1} + +do_execsql_test 2.19 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING + ) FROM t1 +} {2 10 4 6 6 {} 1 8 3 5 5 {}} + +do_execsql_test 2.20 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING + ) FROM t1 +} {1 5 2 7 3 9 4 11 5 6 6 {}} + +do_execsql_test 2.21 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING + ) FROM t1 +} {1 20 2 18 3 15 4 11 5 6 6 {}} + +do_execsql_test 2.22 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING + ) FROM t1 +} {2 10 4 6 6 {} 1 8 3 5 5 {}} + +do_execsql_test 2.23 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} {1 21 2 20 3 18 4 15 5 11 6 6} + +do_execsql_test 2.24 { + SELECT a, sum(d) OVER ( + PARTITION BY a%2 + ORDER BY d + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} {2 12 4 10 6 6 1 9 3 8 5 5} + +do_execsql_test 2.25 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} {1 21 2 21 3 21 4 21 5 21 6 21} + +do_execsql_test 2.26 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} {2 12 4 12 6 12 1 9 3 9 5 9} + +do_execsql_test 2.27 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t1 +} {1 1 2 2 3 3 4 4 5 5 6 6} + +do_execsql_test 2.28 { + SELECT a, sum(d) OVER ( + PARTITION BY b + ORDER BY d + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t1 +} {2 2 4 4 6 6 1 1 3 3 5 5} + +do_execsql_test 2.29 { + SELECT a, sum(d) OVER ( + ORDER BY d + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} {1 21 2 20 3 18 4 15 5 11 6 6} + +do_execsql_test 2.30 { + SELECT a, sum(d) OVER ( + ORDER BY b + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} {2 21 4 21 6 21 1 9 3 9 5 9} + +do_execsql_test 3.1 { + SELECT a, sum(d) OVER ( + PARTITION BY b ORDER BY d + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} {2 12 4 10 6 6 1 9 3 8 5 5} + +do_execsql_test 3.2 { + SELECT a, sum(d) OVER ( + ORDER BY b + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t1 +} {2 21 4 21 6 21 1 9 3 9 5 9} + +do_execsql_test 3.3 { + SELECT a, sum(d) OVER ( + ORDER BY d + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t1 +} {1 21 2 21 3 21 4 21 5 21 6 21} + +do_execsql_test 3.4 { + SELECT a, sum(d) OVER ( + ORDER BY d/2 + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t1 +} {1 1 2 3 3 6 4 10 5 15 6 21} + +#========================================================================== + +do_execsql_test 4.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t2(a, b) VALUES + (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2), + (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62), + (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78), + (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77), + (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7), + (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43), + (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90), + (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56), + (66,40), (67,43), (68,56), (69,16), (70,75), (71,36), (72,89), (73,98), + (74,76), (75,81), (76,4), (77,94), (78,42), (79,30), (80,78), (81,33), + (82,29), (83,53), (84,63), (85,2), (86,87), (87,37), (88,80), (89,84), + (90,72), (91,41), (92,9), (93,61), (94,73), (95,95), (96,65), (97,13), + (98,58), (99,96), (100,98), (101,1), (102,21), (103,74), (104,65), (105,35), + (106,5), (107,73), (108,11), (109,51), (110,87), (111,41), (112,12), (113,8), + (114,20), (115,31), (116,31), (117,15), (118,95), (119,22), (120,73), + (121,79), (122,88), (123,34), (124,8), (125,11), (126,49), (127,34), + (128,90), (129,59), (130,96), (131,60), (132,55), (133,75), (134,77), + (135,44), (136,2), (137,7), (138,85), (139,57), (140,74), (141,29), (142,70), + (143,59), (144,19), (145,39), (146,26), (147,26), (148,47), (149,80), + (150,90), (151,36), (152,58), (153,47), (154,9), (155,72), (156,72), (157,66), + (158,33), (159,93), (160,75), (161,64), (162,81), (163,9), (164,23), (165,37), + (166,13), (167,12), (168,14), (169,62), (170,91), (171,36), (172,91), + (173,33), (174,15), (175,34), (176,36), (177,99), (178,3), (179,95), (180,69), + (181,58), (182,52), (183,30), (184,50), (185,84), (186,10), (187,84), + (188,33), (189,21), (190,39), (191,44), (192,58), (193,30), (194,38), + (195,34), (196,83), (197,27), (198,82), (199,17), (200,7); +} {} + +do_execsql_test 4.1 { + SELECT a, sum(b) OVER ( + PARTITION BY (b%10) + ORDER BY b + ) FROM t2 ORDER BY a; +} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 140 754 141 133 142 340 143 535 144 46 145 250 146 132 147 132 148 354 149 500 150 770 151 276 152 360 153 354 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 190 250 191 266 192 360 193 120 194 128 195 178 196 770 197 92 198 634 199 38 200 21} + +do_execsql_test 4.2 { + SELECT a, sum(b) OVER ( + PARTITION BY (b%10) + ORDER BY b + RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY a; +} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 140 754 141 133 142 340 143 535 144 46 145 250 146 132 147 132 148 354 149 500 150 770 151 276 152 360 153 354 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 190 250 191 266 192 360 193 120 194 128 195 178 196 770 197 92 198 634 199 38 200 21} + +do_execsql_test 4.3 { + SELECT b, sum(b) OVER ( + ORDER BY b + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY b; +} {0 0 1 1 1 2 2 4 2 6 2 8 3 11 3 14 4 18 5 23 6 29 7 36 7 43 7 50 8 58 8 66 8 74 9 83 9 92 9 101 10 111 11 122 11 133 12 145 12 157 12 169 13 182 13 195 14 209 15 224 15 239 15 254 16 270 16 286 16 302 17 319 19 338 20 358 21 379 21 400 22 422 22 444 23 467 23 490 23 513 24 537 25 562 26 588 26 614 26 640 27 667 27 694 28 722 29 751 29 780 29 809 30 839 30 869 30 899 31 930 31 961 32 993 33 1026 33 1059 33 1092 33 1125 33 1158 34 1192 34 1226 34 1260 34 1294 35 1329 35 1364 36 1400 36 1436 36 1472 36 1508 37 1545 37 1582 38 1620 38 1658 39 1697 39 1736 39 1775 40 1815 41 1856 41 1897 41 1938 42 1980 43 2023 43 2066 44 2110 44 2154 46 2200 46 2246 47 2293 47 2340 47 2387 47 2434 49 2483 50 2533 51 2584 52 2636 53 2689 54 2743 55 2798 55 2853 56 2909 56 2965 56 3021 57 3078 58 3136 58 3194 58 3252 58 3310 59 3369 59 3428 59 3487 59 3546 60 3606 61 3667 61 3728 62 3790 62 3852 63 3915 64 3979 65 4044 65 4109 65 4174 66 4240 67 4307 68 4375 69 4444 70 4514 72 4586 72 4658 72 4730 73 4803 73 4876 73 4949 74 5023 74 5097 74 5171 74 5245 74 5319 75 5394 75 5469 75 5544 76 5620 77 5697 77 5774 78 5852 78 5930 79 6009 80 6089 80 6169 81 6250 81 6331 81 6412 82 6494 83 6577 84 6661 84 6745 84 6829 84 6913 85 6998 85 7083 85 7168 86 7254 87 7341 87 7428 88 7516 89 7605 89 7694 89 7783 90 7873 90 7963 90 8053 91 8144 91 8235 91 8326 91 8417 91 8508 93 8601 93 8694 93 8787 94 8881 95 8976 95 9071 95 9166 96 9262 96 9358 96 9454 97 9551 97 9648 98 9746 98 9844 99 9943 99 10042 99 10141} + +do_execsql_test 4.4 { + SELECT b, sum(b) OVER ( + ORDER BY b + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY b; +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} + +do_execsql_test 4.5 { + SELECT b, sum(b) OVER ( + ORDER BY b + RANGE BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY b; +} {0 0 1 2 1 2 2 6 2 6 2 6 3 6 3 6 4 4 5 5 6 6 7 21 7 21 7 21 8 24 8 24 8 24 9 27 9 27 9 27 10 10 11 22 11 22 12 36 12 36 12 36 13 26 13 26 14 14 15 45 15 45 15 45 16 48 16 48 16 48 17 17 19 19 20 20 21 42 21 42 22 44 22 44 23 69 23 69 23 69 24 24 25 25 26 78 26 78 26 78 27 54 27 54 28 28 29 87 29 87 29 87 30 90 30 90 30 90 31 62 31 62 32 32 33 165 33 165 33 165 33 165 33 165 34 136 34 136 34 136 34 136 35 70 35 70 36 144 36 144 36 144 36 144 37 74 37 74 38 76 38 76 39 117 39 117 39 117 40 40 41 123 41 123 41 123 42 42 43 86 43 86 44 88 44 88 46 92 46 92 47 188 47 188 47 188 47 188 49 49 50 50 51 51 52 52 53 53 54 54 55 110 55 110 56 168 56 168 56 168 57 57 58 232 58 232 58 232 58 232 59 236 59 236 59 236 59 236 60 60 61 122 61 122 62 124 62 124 63 63 64 64 65 195 65 195 65 195 66 66 67 67 68 68 69 69 70 70 72 216 72 216 72 216 73 219 73 219 73 219 74 370 74 370 74 370 74 370 74 370 75 225 75 225 75 225 76 76 77 154 77 154 78 156 78 156 79 79 80 160 80 160 81 243 81 243 81 243 82 82 83 83 84 336 84 336 84 336 84 336 85 255 85 255 85 255 86 86 87 174 87 174 88 88 89 267 89 267 89 267 90 270 90 270 90 270 91 455 91 455 91 455 91 455 91 455 93 279 93 279 93 279 94 94 95 285 95 285 95 285 96 288 96 288 96 288 97 194 97 194 98 196 98 196 99 297 99 297 99 297} + +do_execsql_test 4.6.1 { + SELECT b, sum(b) OVER ( + RANGE BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY b; +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} + +do_execsql_test 4.6.2 { + SELECT b, sum(b) OVER () FROM t2 ORDER BY b; +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} + +do_execsql_test 4.6.3 { + SELECT b, sum(b) OVER ( + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY b; +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} + +do_execsql_test 4.6.4 { + SELECT b, sum(b) OVER ( + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY b; +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} + +do_execsql_test 4.7.1 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 98 98 98 98 99 99 99 99 99 99} + +do_execsql_test 4.7.2 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 98 3888 98 5442 99 311 99 1146 99 9093} + +do_execsql_test 4.7.3 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} + +do_execsql_test 4.7.4 { + SELECT b, sum(b) OVER ( + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929} + +do_execsql_test 4.8.1 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN CURRENT ROW AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 98 98 98 98 99 99 99 99 99 99} + +do_execsql_test 4.8.2 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) FROM t2 ORDER BY 1, 2; +} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 98 3888 98 5442 99 311 99 1146 99 9093} + +do_execsql_test 4.8.3 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} + +do_execsql_test 4.8.4 { + SELECT b, sum(b) OVER ( + ORDER BY a + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t2 ORDER BY 1, 2; +} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929} + +finish_test diff --git a/test/window3.tcl b/test/window3.tcl new file mode 100644 index 0000000000..101244e2a4 --- /dev/null +++ b/test/window3.tcl @@ -0,0 +1,337 @@ +# 2018 May 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname $argv0] pg_common.tcl] + +#========================================================================= + +start_test window3 "2018 May 31" +ifcapable !windowfunc + +execsql_test 1.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t2(a, b) VALUES + (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2), + (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62), + (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78), + (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77), + (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7), + (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43), + (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90), + (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56), + (66,40), (67,43), (68,56), (69,16), (70,75), (71,36), (72,89), (73,98), + (74,76), (75,81), (76,4), (77,94), (78,42), (79,30), (80,78), (81,33), + (82,29), (83,53), (84,63), (85,2), (86,87), (87,37), (88,80), (89,84), + (90,72), (91,41), (92,9), (93,61), (94,73), (95,95), (96,65), (97,13), + (98,58), (99,96), (100,98), (101,1), (102,21), (103,74), (104,65), (105,35), + (106,5), (107,73), (108,11), (109,51), (110,87), (111,41), (112,12), (113,8), + (114,20), (115,31), (116,31), (117,15), (118,95), (119,22), (120,73), + (121,79), (122,88), (123,34), (124,8), (125,11), (126,49), (127,34), + (128,90), (129,59), (130,96), (131,60), (132,55), (133,75), (134,77), + (135,44), (136,2), (137,7), (138,85), (139,57), (140,74), (141,29), (142,70), + (143,59), (144,19), (145,39), (146,26), (147,26), (148,47), (149,80), + (150,90), (151,36), (152,58), (153,47), (154,9), (155,72), (156,72), (157,66), + (158,33), (159,93), (160,75), (161,64), (162,81), (163,9), (164,23), (165,37), + (166,13), (167,12), (168,14), (169,62), (170,91), (171,36), (172,91), + (173,33), (174,15), (175,34), (176,36), (177,99), (178,3), (179,95), (180,69), + (181,58), (182,52), (183,30), (184,50), (185,84), (186,10), (187,84), + (188,33), (189,21), (190,39), (191,44), (192,58), (193,30), (194,38), + (195,34), (196,83), (197,27), (198,82), (199,17), (200,7); +} + +execsql_test 1.1 { + SELECT max(b) OVER ( + ORDER BY a + ) FROM t2 +} + +foreach {tn window} { + 1 "RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" + 2 "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING" + 3 "RANGE BETWEEN CURRENT ROW AND CURRENT ROW" + 4 "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" + 5 "ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING" + 6 "ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING" + 7 "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" + 8 "ROWS BETWEEN 4 PRECEDING AND CURRENT ROW" + 9 "ROWS BETWEEN CURRENT ROW AND CURRENT ROW" + 10 "ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING" + 11 "ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING" + 12 "ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING" + 13 "ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING" + 14 "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING" + 15 "ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING" + 16 "ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" + 17 "ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING" +} { + execsql_test 1.$tn.2.1 "SELECT max(b) OVER ( ORDER BY a $window ) FROM t2" + execsql_test 1.$tn.2.2 "SELECT min(b) OVER ( ORDER BY a $window ) FROM t2" + + execsql_test 1.$tn.3.1 " + SELECT row_number() OVER ( ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.3.2 " + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.3.3 " + SELECT row_number() OVER ( $window ) FROM t2 + " + + execsql_test 1.$tn.4.1 " + SELECT dense_rank() OVER ( ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.4.2 " + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.4.3 " + SELECT dense_rank() OVER ( ORDER BY b $window ) FROM t2 + " + execsql_test 1.$tn.4.4 " + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2 + " + execsql_test 1.$tn.4.5 " + SELECT dense_rank() OVER ( ORDER BY b%10 $window ) FROM t2 + " + execsql_test 1.$tn.4.6 " + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ) FROM t2 + " + + execsql_test 1.$tn.5.1 " + SELECT rank() OVER ( ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.5.2 " + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.5.3 " + SELECT rank() OVER ( ORDER BY b $window ) FROM t2 + " + execsql_test 1.$tn.5.4 " + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2 + " + execsql_test 1.$tn.5.5 " + SELECT rank() OVER ( ORDER BY b%10 $window ) FROM t2 + " + execsql_test 1.$tn.5.6 " + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ) FROM t2 + " + + execsql_test 1.$tn.6.1 " + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ) + FROM t2 + " + + execsql_float_test 1.$tn.7.1 " + SELECT percent_rank() OVER ( ORDER BY a $window ) FROM t2 + " + execsql_float_test 1.$tn.7.2 " + SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2 + " + execsql_float_test 1.$tn.7.3 " + SELECT percent_rank() OVER ( ORDER BY b $window ) FROM t2 + " + execsql_float_test 1.$tn.7.4 " + SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2 + " + execsql_float_test 1.$tn.7.5 " + SELECT percent_rank() OVER ( ORDER BY b%10 $window ) FROM t2 + " + execsql_float_test 1.$tn.7.6 " + SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 $window) FROM t2 + " + + execsql_float_test 1.$tn.8.1 " + SELECT cume_dist() OVER ( ORDER BY a $window ) FROM t2 + " + execsql_float_test 1.$tn.8.2 " + SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2 + " + execsql_float_test 1.$tn.8.3 " + SELECT cume_dist() OVER ( ORDER BY b $window ) FROM t2 + " + execsql_float_test 1.$tn.8.4 " + SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2 + " + execsql_float_test 1.$tn.8.5 " + SELECT cume_dist() OVER ( ORDER BY b%10 $window ) FROM t2 + " + execsql_float_test 1.$tn.8.6 " + SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ) FROM t2 + " + + execsql_float_test 1.$tn.8.1 " + SELECT ntile(100) OVER ( ORDER BY a $window ) FROM t2 + " + execsql_float_test 1.$tn.8.2 " + SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2 + " + execsql_float_test 1.$tn.8.3 " + SELECT ntile(102) OVER ( ORDER BY b,a $window ) FROM t2 + " + execsql_float_test 1.$tn.8.4 " + SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2 + " + execsql_float_test 1.$tn.8.5 " + SELECT ntile(104) OVER ( ORDER BY b%10,a $window ) FROM t2 + " + execsql_float_test 1.$tn.8.6 " + SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2 + " + execsql_float_test 1.$tn.8.7 " + SELECT ntile(105) OVER ( $window ) FROM t2 + " + + execsql_test 1.$tn.9.1 " + SELECT last_value(a+b) OVER ( ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.9.2 " + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2 + " + execsql_test 1.$tn.9.3 " + SELECT last_value(a+b) OVER ( ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.9.4 " + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.9.5 " + SELECT last_value(a+b) OVER ( ORDER BY b%10,a $window ) FROM t2 + " + execsql_test 1.$tn.9.6 " + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2 + " + + execsql_test 1.$tn.10.1 " + SELECT nth_value(b,b+1) OVER (ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.10.2 " + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.10.3 " + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.10.4 " + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.10.5 " + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a $window ) FROM t2 + " + execsql_test 1.$tn.10.6 " + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2 + " + + execsql_test 1.$tn.11.1 " + SELECT first_value(b) OVER (ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.11.2 " + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.11.3 " + SELECT first_value(b) OVER ( ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.11.4 " + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.11.5 " + SELECT first_value(b) OVER ( ORDER BY b%10,a $window ) FROM t2 + " + execsql_test 1.$tn.11.6 " + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2 + " + + execsql_test 1.$tn.12.1 " + SELECT lead(b,b) OVER (ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.12.2 " + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.12.3 " + SELECT lead(b,b) OVER ( ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.12.4 " + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.12.5 " + SELECT lead(b,b) OVER ( ORDER BY b%10,a $window ) FROM t2 + " + execsql_test 1.$tn.12.6 " + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2 + " + + execsql_test 1.$tn.13.1 " + SELECT lag(b,b) OVER (ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.13.2 " + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.13.3 " + SELECT lag(b,b) OVER ( ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.13.4 " + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.13.5 " + SELECT lag(b,b) OVER ( ORDER BY b%10,a $window ) FROM t2 + " + execsql_test 1.$tn.13.6 " + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2 + " + + execsql_test 1.$tn.14.1 " + SELECT string_agg(CAST(b AS TEXT), '.') OVER (ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.14.2 " + SELECT string_agg(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2 + " + execsql_test 1.$tn.14.3 " + SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.14.4 " + SELECT string_agg(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2 + " + execsql_test 1.$tn.14.5 " + SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a $window ) FROM t2 + " + execsql_test 1.$tn.14.6 " + SELECT string_agg(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2 + " + + execsql_test 1.$tn.15.1 " + SELECT count(*) OVER win, string_agg(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a $window) + " + + execsql_test 1.$tn.15.2 " + SELECT count(*) OVER win, string_agg(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a $window) + " + + execsql_test 1.$tn.15.3 " + SELECT count(*) OVER win, string_agg(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a $window) + " + + execsql_test 1.$tn.15.4 " + SELECT count(*) OVER win, string_agg(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a $window) + " + +} + +finish_test + diff --git a/test/window3.test b/test/window3.test new file mode 100644 index 0000000000..a9e0c64eb8 --- /dev/null +++ b/test/window3.test @@ -0,0 +1,9054 @@ +# 2018 May 31 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +#################################################### +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! +#################################################### + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix window3 + +ifcapable !windowfunc { finish_test ; return } +do_execsql_test 1.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t2(a, b) VALUES + (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2), + (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62), + (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78), + (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77), + (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7), + (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43), + (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90), + (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56), + (66,40), (67,43), (68,56), (69,16), (70,75), (71,36), (72,89), (73,98), + (74,76), (75,81), (76,4), (77,94), (78,42), (79,30), (80,78), (81,33), + (82,29), (83,53), (84,63), (85,2), (86,87), (87,37), (88,80), (89,84), + (90,72), (91,41), (92,9), (93,61), (94,73), (95,95), (96,65), (97,13), + (98,58), (99,96), (100,98), (101,1), (102,21), (103,74), (104,65), (105,35), + (106,5), (107,73), (108,11), (109,51), (110,87), (111,41), (112,12), (113,8), + (114,20), (115,31), (116,31), (117,15), (118,95), (119,22), (120,73), + (121,79), (122,88), (123,34), (124,8), (125,11), (126,49), (127,34), + (128,90), (129,59), (130,96), (131,60), (132,55), (133,75), (134,77), + (135,44), (136,2), (137,7), (138,85), (139,57), (140,74), (141,29), (142,70), + (143,59), (144,19), (145,39), (146,26), (147,26), (148,47), (149,80), + (150,90), (151,36), (152,58), (153,47), (154,9), (155,72), (156,72), (157,66), + (158,33), (159,93), (160,75), (161,64), (162,81), (163,9), (164,23), (165,37), + (166,13), (167,12), (168,14), (169,62), (170,91), (171,36), (172,91), + (173,33), (174,15), (175,34), (176,36), (177,99), (178,3), (179,95), (180,69), + (181,58), (182,52), (183,30), (184,50), (185,84), (186,10), (187,84), + (188,33), (189,21), (190,39), (191,44), (192,58), (193,30), (194,38), + (195,34), (196,83), (197,27), (198,82), (199,17), (200,7), (201,5); +} {} + +do_execsql_test 1.1 { + SELECT max(b) OVER ( + ORDER BY a + ) FROM t2 +} {0 74 74 74 74 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.1.2.1 { + SELECT max(b) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 74 74 74 74 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.1.2.2 { + SELECT min(b) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.1.3.1 { + SELECT row_number() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.1.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.1.3.3 { + SELECT row_number() OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.1.4.1 { + SELECT dense_rank() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.1.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.1.4.3 { + SELECT dense_rank() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.1.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.1.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.1.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.1.5.1 { + SELECT rank() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.1.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.1.5.3 { + SELECT rank() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.1.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.1.5.5 { + SELECT rank() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.1.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.1.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.1.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.1.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.1.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 76 44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206} + +do_execsql_test 1.1.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.1.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 65 102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276} + +do_execsql_test 1.1.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 196 134 109 213 223 106 234 191 212 168 229 147 218 240 65 102 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 11 87 138 63 124 179 78 141 84 120 234 79 231 162 227 228 280 57 181 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 80 182 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 111 206 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 26 51 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 48 144 207 216 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 36 121 132 88 52 232 156 210 239 250 83 103 158 210 171 198 101 163 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276} + +do_execsql_test 1.1.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.1.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.1.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 41 {} {} {} {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} 2 {} 29 {} {} {} 46 62 62 {} {} 16 {} 33 {} {} {} {} {} 78 {} 61 {} 59 77 {} 74 {} 27 {} 22 39 67 {} 54 85 74 90 7 61 90 62 {} 93 {} {} {} {} 23 {} 74 93 30 23 29 3 1 41 {} 65 33 2 98 86 89 25 76 {} 40 38 15 13 96 74 97 81 40 16 99 76 96 32 80 86 59 2 99 84 84 39 65 27 76 78 84 16 2 96 59 16 41 28 13 89 22 4 42 91 41 33 87 55 81 29 36 28 6 47 97 97 85 33 41 93 15 85 89 98 98 43 23 73 4 56 29 89 46 65 38 59 68 47 9 93 9 23 39 16 93 98 74 65 75 15 56 93 12 2 81 2 23 97 47 91 15 93 35 16 63 8 53 91 33 99} + +do_execsql_test 1.1.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 81 {} {} {} 81 {} 21 {} {} {} {} 21 {} {} {} 21 {} {} {} {} {} {} 12 {} {} {} 12 {} {} 72 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 73 {} 23 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 15 {} {} {} {} {} {} 55 {} 15 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 47 {} {} {} {} {} {} {} {} {} 98 {} 98 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 29 {} {} {} {} {} {} {} 29 29 {} {} {}} + +do_execsql_test 1.1.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 8 9 9 10 10 11 11 11 11 11 12 12 12 12 12 13 13 13 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 25 25 25 25 26 26 27 27 28 29 29 29 29 29 29 30 30 30 30 30 30 30 30 30 31 31 31 32 32 33 33 33 33 33 33 33 34 34 34 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 36 37 37 37 38 38 38 38 38 39 39 39 39 39 39 40 40 40 41 41 41 41 42 42 42 43 43 43 43 43 43 43 43 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 47 47} + +do_execsql_test 1.1.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 90 {} {} {} 90 1 30 {} {} {} 31 30 {} {} {} 1 40 {} 50 11 81 42 40 {} 50 81 40 {} {} 50 {} 52 {} 41 81 {} 41 {} 2 30 2 81 82 53 {} 10 {} {} 81 {} 41 10 81 30 81 {} 3 3 23 {} 3 61 80 {} 94 3 91 91 72 3 63 30 91 94 94 72 91 73 91 84 84 33 41 1 33 84 73 73 91 20 41 84 33 33 84 33 41 84 20 21 44 22 90 22 81 81 74 93 93 93 81 21 83 44 44 21 21 21 13 21 21 34 11 34 73 74 2 60 2 34 2 34 74 60 23 2 2 2 11 91 60 62 73 74 70 51 65 74 93 65 70 34 70 93 93 93 62 35 44 43 12 35 41 43 44 44 41 80 54 72 43 41 43 91 12 80 80 35 33 12} + +do_execsql_test 1.1.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.11.1 { + SELECT first_value(b) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.1.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.1.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.1.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9} + +do_execsql_test 1.1.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.1.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.1.12.1 { + SELECT lead(b,b) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.13.1 { + SELECT lag(b,b) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.1.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.1.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.1.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.1.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.1.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0.74 0.74.41 0.74.41.74 0.74.41.74.23 0.74.41.74.23.99 0.74.41.74.23.99.26 0.74.41.74.23.99.26.33 0.74.41.74.23.99.26.33.2 0.74.41.74.23.99.26.33.2.89 0.74.41.74.23.99.26.33.2.89.81 0.74.41.74.23.99.26.33.2.89.81.96 0.74.41.74.23.99.26.33.2.89.81.96.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5} + +do_execsql_test 1.1.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 0.90.40.30.80.20.90.60.70.80.90.30 0.90.40.30.80.20.90.60.70.80.90.30.50 0.90.40.30.80.20.90.60.70.80.90.30.50.10 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 41 41.81 41.81.91 41.81.91.61 41.81.91.61.91 41.81.91.61.91.91 41.81.91.61.91.91.1 41.81.91.61.91.91.1.81 41.81.91.61.91.91.1.81.41 41.81.91.61.91.91.1.81.41.61 41.81.91.61.91.91.1.81.41.61.1 41.81.91.61.91.91.1.81.41.61.1.21 41.81.91.61.91.91.1.81.41.61.1.21.11 41.81.91.61.91.91.1.81.41.61.1.21.11.51 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 2 2.62 2.62.12 2.62.12.32 2.62.12.32.22 2.62.12.32.22.42 2.62.12.32.22.42.2 2.62.12.32.22.42.2.72 2.62.12.32.22.42.2.72.12 2.62.12.32.22.42.2.72.12.22 2.62.12.32.22.42.2.72.12.22.2 2.62.12.32.22.42.2.72.12.22.2.72 2.62.12.32.22.42.2.72.12.22.2.72.72 2.62.12.32.22.42.2.72.12.22.2.72.72.12 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 23 23.33 23.33.93 23.33.93.23 23.33.93.23.93 23.33.93.23.93.43 23.33.93.23.93.43.3 23.33.93.23.93.43.3.43 23.33.93.23.93.43.3.43.33 23.33.93.23.93.43.3.43.33.53 23.33.93.23.93.43.3.43.33.53.63 23.33.93.23.93.43.3.43.33.53.63.73 23.33.93.23.93.43.3.43.33.53.63.73.13 23.33.93.23.93.43.3.43.33.53.63.73.13.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 74 74.74 74.74.54 74.74.54.84 74.74.54.84.74 74.74.54.84.74.24 74.74.54.84.74.24.4 74.74.54.84.74.24.4.94 74.74.54.84.74.24.4.94.84 74.74.54.84.74.24.4.94.84.74 74.74.54.84.74.24.4.94.84.74.34 74.74.54.84.74.24.4.94.84.74.34.34 74.74.54.84.74.24.4.94.84.74.34.34.44 74.74.54.84.74.24.4.94.84.74.34.34.44.74 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 65 65.35 65.35.85 65.35.85.85 65.35.85.85.55 65.35.85.85.55.15 65.35.85.85.55.15.25 65.35.85.85.55.15.25.75 65.35.85.85.55.15.25.75.95 65.35.85.85.55.15.25.75.95.65 65.35.85.85.55.15.25.75.95.65.65 65.35.85.85.55.15.25.75.95.65.65.35 65.35.85.85.55.15.25.75.95.65.65.35.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 26 26.96 26.96.46 26.96.46.6 26.96.46.6.46 26.96.46.6.46.16 26.96.46.6.46.16.16 26.96.46.6.46.16.16.86 26.96.46.6.46.16.16.86.56 26.96.46.6.46.16.16.86.56.56 26.96.46.6.46.16.16.86.56.56.56 26.96.46.6.46.16.16.86.56.56.56.16 26.96.46.6.46.16.16.86.56.56.56.16.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 97 97.27 97.27.97 97.27.97.67 97.27.97.67.77 97.27.97.67.77.47 97.27.97.67.77.47.7 97.27.97.67.77.47.7.47 97.27.97.67.77.47.7.47.87 97.27.97.67.77.47.7.47.87.37 97.27.97.67.77.47.7.47.87.37.87 97.27.97.67.77.47.7.47.87.37.87.77 97.27.97.67.77.47.7.47.87.37.87.77.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 38 38.68 38.68.78 38.68.78.8 38.68.78.8.28 38.68.78.8.28.98 38.68.78.8.28.98.78 38.68.78.8.28.98.78.58 38.68.78.8.28.98.78.58.98 38.68.78.8.28.98.78.58.98.8 38.68.78.8.28.98.78.58.98.8.88 38.68.78.8.28.98.78.58.98.8.88.8 38.68.78.8.28.98.78.58.98.8.88.8.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 99 99.89 99.89.59 99.89.59.39 99.89.59.39.99 99.89.59.39.99.29 99.89.59.39.99.29.59 99.89.59.39.99.29.59.89 99.89.59.39.99.29.59.89.89 99.89.59.39.99.29.59.89.89.29 99.89.59.39.99.29.59.89.89.29.9 99.89.59.39.99.29.59.89.89.29.9.79 99.89.59.39.99.29.59.89.89.29.9.79.49 99.89.59.39.99.29.59.89.89.29.9.79.49.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.1.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.1 0.1.1 0.1.1.2 0.1.1.2.2 0.1.1.2.2.2 0.1.1.2.2.2.3 0.1.1.2.2.2.3.3 0.1.1.2.2.2.3.3.4 0.1.1.2.2.2.3.3.4.5 0.1.1.2.2.2.3.3.4.5.5 0.1.1.2.2.2.3.3.4.5.5.6 0.1.1.2.2.2.3.3.4.5.5.6.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99} + +do_execsql_test 1.1.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.10 0.10.20 0.10.20.30 0.10.20.30.30 0.10.20.30.30.30 0.10.20.30.30.30.40 0.10.20.30.30.30.40.50 0.10.20.30.30.30.40.50.60 0.10.20.30.30.30.40.50.60.70 0.10.20.30.30.30.40.50.60.70.80 0.10.20.30.30.30.40.50.60.70.80.80 0.10.20.30.30.30.40.50.60.70.80.80.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 1 1.1 1.1.11 1.1.11.11 1.1.11.11.21 1.1.11.11.21.21 1.1.11.11.21.21.31 1.1.11.11.21.21.31.31 1.1.11.11.21.21.31.31.41 1.1.11.11.21.21.31.31.41.41 1.1.11.11.21.21.31.31.41.41.41 1.1.11.11.21.21.31.31.41.41.41.51 1.1.11.11.21.21.31.31.41.41.41.51.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 2 2.2 2.2.2 2.2.2.12 2.2.2.12.12 2.2.2.12.12.12 2.2.2.12.12.12.22 2.2.2.12.12.12.22.22 2.2.2.12.12.12.22.22.32 2.2.2.12.12.12.22.22.32.42 2.2.2.12.12.12.22.22.32.42.52 2.2.2.12.12.12.22.22.32.42.52.62 2.2.2.12.12.12.22.22.32.42.52.62.62 2.2.2.12.12.12.22.22.32.42.52.62.62.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 3 3.3 3.3.13 3.3.13.13 3.3.13.13.23 3.3.13.13.23.23 3.3.13.13.23.23.23 3.3.13.13.23.23.23.33 3.3.13.13.23.23.23.33.33 3.3.13.13.23.23.23.33.33.33 3.3.13.13.23.23.23.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 4 4.14 4.14.24 4.14.24.34 4.14.24.34.34 4.14.24.34.34.34 4.14.24.34.34.34.34 4.14.24.34.34.34.34.44 4.14.24.34.34.34.34.44.44 4.14.24.34.34.34.34.44.44.54 4.14.24.34.34.34.34.44.44.54.64 4.14.24.34.34.34.34.44.44.54.64.74 4.14.24.34.34.34.34.44.44.54.64.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 5 5.5 5.5.15 5.5.15.15 5.5.15.15.15 5.5.15.15.15.25 5.5.15.15.15.25.35 5.5.15.15.15.25.35.35 5.5.15.15.15.25.35.35.55 5.5.15.15.15.25.35.35.55.55 5.5.15.15.15.25.35.35.55.55.65 5.5.15.15.15.25.35.35.55.55.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 6 6.16 6.16.16 6.16.16.16 6.16.16.16.26 6.16.16.16.26.26 6.16.16.16.26.26.26 6.16.16.16.26.26.26.36 6.16.16.16.26.26.26.36.36 6.16.16.16.26.26.26.36.36.36 6.16.16.16.26.26.26.36.36.36.36 6.16.16.16.26.26.26.36.36.36.36.46 6.16.16.16.26.26.26.36.36.36.36.46.46 6.16.16.16.26.26.26.36.36.36.36.46.46.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 7 7.7 7.7.7 7.7.7.17 7.7.7.17.27 7.7.7.17.27.27 7.7.7.17.27.27.37 7.7.7.17.27.27.37.37 7.7.7.17.27.27.37.37.47 7.7.7.17.27.27.37.37.47.47 7.7.7.17.27.27.37.37.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47.57 7.7.7.17.27.27.37.37.47.47.47.47.57.67 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 8 8.8 8.8.8 8.8.8.28 8.8.8.28.38 8.8.8.28.38.38 8.8.8.28.38.38.58 8.8.8.28.38.38.58.58 8.8.8.28.38.38.58.58.58 8.8.8.28.38.38.58.58.58.58 8.8.8.28.38.38.58.58.58.58.68 8.8.8.28.38.38.58.58.58.58.68.78 8.8.8.28.38.38.58.58.58.58.68.78.78 8.8.8.28.38.38.58.58.58.58.68.78.78.88 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 9 9.9 9.9.9 9.9.9.19 9.9.9.19.29 9.9.9.19.29.29 9.9.9.19.29.29.29 9.9.9.19.29.29.29.39 9.9.9.19.29.29.29.39.39 9.9.9.19.29.29.29.39.39.39 9.9.9.19.29.29.29.39.39.39.49 9.9.9.19.29.29.29.39.39.39.49.59 9.9.9.19.29.29.29.39.39.39.49.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99} + +do_execsql_test 1.1.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 0.90.40.30.80.20.90.60.70.80.90.30 0.90.40.30.80.20.90.60.70.80.90.30.50 0.90.40.30.80.20.90.60.70.80.90.30.50.10 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.1.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.1.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {1 {} 2 74 3 74 4 74.74 5 74.74 6 74.74.99 7 74.74.99 8 74.74.99.33 9 74.74.99.33 10 74.74.99.33.89 11 74.74.99.33.89 12 74.74.99.33.89.96 13 74.74.99.33.89.96 14 74.74.99.33.89.96.38 15 74.74.99.33.89.96.38 16 74.74.99.33.89.96.38.39 17 74.74.99.33.89.96.38.39 18 74.74.99.33.89.96.38.39.91 19 74.74.99.33.89.96.38.39.91 20 74.74.99.33.89.96.38.39.91.6 21 74.74.99.33.89.96.38.39.91.6 22 74.74.99.33.89.96.38.39.91.6.97 23 74.74.99.33.89.96.38.39.91.6.97 24 74.74.99.33.89.96.38.39.91.6.97.46 25 74.74.99.33.89.96.38.39.91.6.97.46 26 74.74.99.33.89.96.38.39.91.6.97.46.54 27 74.74.99.33.89.96.38.39.91.6.97.46.54 28 74.74.99.33.89.96.38.39.91.6.97.46.54.8 29 74.74.99.33.89.96.38.39.91.6.97.46.54.8 30 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 31 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 32 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 33 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 34 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 35 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 36 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 37 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 38 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 39 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 40 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 41 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 42 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 43 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 44 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 45 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 46 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 47 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 48 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 49 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 50 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 51 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 52 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 53 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 54 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 55 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 56 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 57 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 58 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 59 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 60 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 61 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 62 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 63 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 64 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 65 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 66 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 67 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 68 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 69 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 70 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 71 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 72 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 73 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 74 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 75 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 76 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 77 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 78 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 79 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 80 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 81 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 82 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 83 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 84 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 85 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 86 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 87 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 88 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 89 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 90 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 91 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 92 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 93 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 94 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 95 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 96 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 97 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 98 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 99 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 100 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 101 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 102 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 103 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 104 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 105 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 106 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 107 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 108 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 109 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 110 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 111 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 112 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 113 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 114 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 115 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 116 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 117 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 118 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 119 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 120 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 121 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 122 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 123 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 124 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 125 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 126 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 127 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 128 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 129 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 130 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 131 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 132 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 133 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 134 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 135 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 136 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 137 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 138 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 139 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 140 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 141 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 142 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 143 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 144 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 145 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 146 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 147 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 148 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 149 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 150 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 151 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 152 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 153 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 154 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 155 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 156 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 157 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 158 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 159 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 160 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 161 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 162 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 163 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 164 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 165 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 166 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 167 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 168 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 169 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 170 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 171 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 172 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 173 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 174 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 175 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 176 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 177 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 178 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 179 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 180 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 181 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 182 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 183 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 184 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 185 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 186 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 187 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 188 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 189 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 190 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 191 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 192 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 193 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 194 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 195 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 196 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83 197 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83 198 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82 199 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82 200 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7} + +do_execsql_test 1.1.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {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 {}} + +do_execsql_test 1.1.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 21 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {}} + +do_execsql_test 1.1.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {1 89 2 89.6 3 89.6.29 4 89.6.29.47 5 89.6.29.47.59 6 89.6.29.47.59.28 7 89.6.29.47.59.28.75 8 89.6.29.47.59.28.75.78 9 89.6.29.47.59.28.75.78.72 10 89.6.29.47.59.28.75.78.72.98 11 89.6.29.47.59.28.75.78.72.98.87 12 89.6.29.47.59.28.75.78.72.98.87.73 13 89.6.29.47.59.28.75.78.72.98.87.73.96 14 89.6.29.47.59.28.75.78.72.98.87.73.96.74 15 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90 16 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75 17 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91 18 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69 19 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 21 {} 1 74 2 74.96 3 74.96.97 4 74.96.97.84 5 74.96.97.84.86 6 74.96.97.84.86.32 7 74.96.97.84.86.32.25 8 74.96.97.84.86.32.25.89 9 74.96.97.84.86.32.25.89.29 10 74.96.97.84.86.32.25.89.29.9 11 74.96.97.84.86.32.25.89.29.9.21 12 74.96.97.84.86.32.25.89.29.9.21.12 13 74.96.97.84.86.32.25.89.29.9.21.12.88 14 74.96.97.84.86.32.25.89.29.9.21.12.88.55 15 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70 16 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58 17 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81 18 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91 19 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 74 2 74.38 3 74.38.46 4 74.38.46.23 5 74.38.46.23.61 6 74.38.46.23.61.3 7 74.38.46.23.61.3.1 8 74.38.46.23.61.3.1.76 9 74.38.46.23.61.3.1.76.63 10 74.38.46.23.61.3.1.76.63.73 11 74.38.46.23.61.3.1.76.63.73.65 12 74.38.46.23.61.3.1.76.63.73.65.20 13 74.38.46.23.61.3.1.76.63.73.65.20.8 14 74.38.46.23.61.3.1.76.63.73.65.20.8.77 15 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19 16 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9 17 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23 18 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15 19 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 99 2 99.39 3 99.39.54 4 99.39.54.16 5 99.39.54.16.85 6 99.39.54.16.85.22 7 99.39.54.16.85.22.40 8 99.39.54.16.85.22.40.4 9 99.39.54.16.85.22.40.4.87 10 99.39.54.16.85.22.40.4.87.65 11 99.39.54.16.85.22.40.4.87.65.5 12 99.39.54.16.85.22.40.4.87.65.5.31 13 99.39.54.16.85.22.40.4.87.65.5.31.49 14 99.39.54.16.85.22.40.4.87.65.5.31.49.2 15 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26 16 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72 17 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13 18 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36 19 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 33 2 33.91 3 33.91.8 4 33.91.8.65 5 33.91.8.65.85 6 33.91.8.65.85.55 7 33.91.8.65.85.55.56 8 33.91.8.65.85.55.56.42 9 33.91.8.65.85.55.56.42.80 10 33.91.8.65.85.55.56.42.80.58 11 33.91.8.65.85.55.56.42.80.58.11 12 33.91.8.65.85.55.56.42.80.58.11.95 13 33.91.8.65.85.55.56.42.80.58.11.95.90 14 33.91.8.65.85.55.56.42.80.58.11.95.90.85 15 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47 16 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33 17 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14 18 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3 19 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {}} + +do_execsql_test 1.2.2.1 { + SELECT max(b) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.2.2.2 { + SELECT min(b) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.2.3.1 { + SELECT row_number() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.2.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.2.3.3 { + SELECT row_number() OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.2.4.1 { + SELECT dense_rank() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.2.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.2.4.3 { + SELECT dense_rank() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.2.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.2.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.2.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.2.5.1 { + SELECT rank() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.2.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.2.5.3 { + SELECT rank() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.2.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.2.5.5 { + SELECT rank() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.2.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.2.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.2.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.2.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.2.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206} + +do_execsql_test 1.2.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.2.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.2.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.2.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.2.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.2.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 81 86 81 46 98 97 23 41 72 29 13 28 35 16 47 47 9 24 26 98 58 8 24 30 91 58 2 56 29 73 2 42 46 62 62 73 40 16 85 33 37 81 25 9 87 78 87 61 28 59 77 90 74 9 27 41 22 39 67 72 54 85 74 90 7 61 90 62 4 93 72 96 94 29 23 95 74 93 30 23 29 3 1 41 80 65 33 2 98 86 89 25 76 65 40 38 15 13 96 74 97 81 40 16 99 76 96 32 80 86 59 2 99 84 84 39 65 27 76 78 84 16 2 96 59 16 41 28 13 89 22 4 42 91 41 33 87 55 81 29 36 28 6 47 97 97 85 33 41 93 15 85 89 98 98 43 23 73 4 56 29 89 46 65 38 59 68 47 9 93 9 23 39 16 93 98 74 65 75 15 56 93 12 2 81 2 23 97 47 91 15 93 35 16 63 8 53 91 33 99} + +do_execsql_test 1.2.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 81 {} {} {} 81 21 21 {} {} {} {} 21 {} {} {} 21 12 {} 72 {} {} {} 12 {} 72 {} 12 {} {} 72 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} 73 {} {} {} {} {} 73 {} 23 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} 55 {} {} {} {} {} {} 15 55 {} {} {} {} {} 55 {} 15 {} {} {} 16 {} 26 26 {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 47 {} {} {} {} {} 27 47 {} {} {} 98 {} {} {} {} {} 98 {} 98 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 29 {} {} {} {} {} 9 {} 29 29 {} {} {}} + +do_execsql_test 1.2.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 8 9 9 10 10 11 11 11 11 11 12 12 12 12 12 13 13 13 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 25 25 25 25 26 26 27 27 28 29 29 29 29 29 29 30 30 30 30 30 30 30 30 30 31 31 31 32 32 33 33 33 33 33 33 33 34 34 34 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 36 37 37 37 38 38 38 38 38 39 39 39 39 39 39 40 40 40 41 41 41 41 42 42 42 43 43 43 43 43 43 43 43 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 47 47} + +do_execsql_test 1.2.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 1 51 51 91 91 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 2 2 62 62 62 {} {} {} {} {} {} {} {} {} {} {} 13 13 43 43 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 25 75 75 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 66 66 66 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 37 37 87 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 58 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 39 39 89 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 74 32 31 84 91 74 3 93 84 74 31 12 90 31 22 74 64 43 64 64 90 74 22 43 90 1 30 62 22 31 31 30 74 64 64 1 40 33 50 11 81 42 40 13 50 81 40 13 13 50 33 52 24 41 81 34 41 34 2 30 2 81 82 53 33 10 33 33 81 34 41 10 81 30 81 4 3 3 23 94 3 61 80 84 94 3 91 91 72 3 63 30 91 94 94 72 91 73 91 84 84 33 41 1 33 84 73 73 91 20 41 84 33 33 84 33 41 84 20 21 44 22 90 22 81 81 74 93 93 93 81 21 83 44 44 21 21 21 13 21 21 34 11 34 73 74 2 60 2 34 2 34 74 60 23 2 2 2 11 91 60 62 73 74 70 51 65 74 93 65 70 34 70 93 93 93 62 35 44 43 12 35 41 43 44 44 41 80 54 72 43 41 43 91 12 80 80 35 33 12} + +do_execsql_test 1.2.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.11.1 { + SELECT first_value(b) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.2.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.2.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.2.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9} + +do_execsql_test 1.2.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.2.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.2.12.1 { + SELECT lead(b,b) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.13.1 { + SELECT lag(b,b) OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.2.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.2.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.2.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.2.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.2.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5} + +do_execsql_test 1.2.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.2.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99} + +do_execsql_test 1.2.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99} + +do_execsql_test 1.2.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.2.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.2.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7} + +do_execsql_test 1.2.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {}} + +do_execsql_test 1.2.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {}} + +do_execsql_test 1.2.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {}} + +do_execsql_test 1.3.2.1 { + SELECT max(b) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.3.2.2 { + SELECT min(b) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.3.3.1 { + SELECT row_number() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.3.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.3.3.3 { + SELECT row_number() OVER ( RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.3.4.1 { + SELECT dense_rank() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.3.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.3.4.3 { + SELECT dense_rank() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.3.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.3.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.3.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.3.5.1 { + SELECT rank() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.3.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.3.5.3 { + SELECT rank() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.3.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.3.5.5 { + SELECT rank() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.3.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.3.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.3.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.3.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.3.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 76 44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206} + +do_execsql_test 1.3.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.3.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 65 102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276} + +do_execsql_test 1.3.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 196 134 109 213 223 106 234 191 212 168 229 147 218 240 65 102 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 11 87 138 63 124 179 78 141 84 120 234 79 231 162 227 228 280 57 181 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 80 182 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 111 206 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 26 51 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 48 144 207 216 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 36 121 132 88 52 232 156 210 239 250 83 103 158 210 171 198 101 163 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276} + +do_execsql_test 1.3.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.3.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.3.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.11.1 { + SELECT first_value(b) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.3.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.3.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99} + +do_execsql_test 1.3.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 10 20 30 30 30 40 50 60 70 80 80 90 90 90 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 2 2 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 8 8 8 28 38 38 58 58 58 58 68 78 78 88 98 98 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99} + +do_execsql_test 1.3.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.3.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.3.12.1 { + SELECT lead(b,b) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.13.1 { + SELECT lag(b,b) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.3.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.3.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.3.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.3.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.3.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.3.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.3.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99} + +do_execsql_test 1.3.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 10 20 30 30 30 40 50 60 70 80 80 90 90 90 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 2 2 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 8 8 8 28 38 38 58 58 58 58 68 78 78 88 98 98 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99} + +do_execsql_test 1.3.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.3.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.3.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 {} 1 74 1 {} 1 74 1 {} 1 99 1 {} 1 33 1 {} 1 89 1 {} 1 96 1 {} 1 38 1 {} 1 39 1 {} 1 91 1 {} 1 6 1 {} 1 97 1 {} 1 46 1 {} 1 54 1 {} 1 8 1 {} 1 29 1 {} 1 84 1 {} 1 23 1 {} 1 16 1 {} 1 65 1 {} 1 47 1 {} 1 86 1 {} 1 61 1 {} 1 85 1 {} 1 85 1 {} 1 59 1 {} 1 32 1 {} 1 3 1 {} 1 22 1 {} 1 55 1 {} 1 28 1 {} 1 25 1 {} 1 1 1 {} 1 40 1 {} 1 56 1 {} 1 75 1 {} 1 89 1 {} 1 76 1 {} 1 4 1 {} 1 42 1 {} 1 78 1 {} 1 29 1 {} 1 63 1 {} 1 87 1 {} 1 80 1 {} 1 72 1 {} 1 9 1 {} 1 73 1 {} 1 65 1 {} 1 58 1 {} 1 98 1 {} 1 21 1 {} 1 65 1 {} 1 5 1 {} 1 11 1 {} 1 87 1 {} 1 12 1 {} 1 20 1 {} 1 31 1 {} 1 95 1 {} 1 73 1 {} 1 88 1 {} 1 8 1 {} 1 49 1 {} 1 90 1 {} 1 96 1 {} 1 55 1 {} 1 77 1 {} 1 2 1 {} 1 85 1 {} 1 74 1 {} 1 70 1 {} 1 19 1 {} 1 26 1 {} 1 47 1 {} 1 90 1 {} 1 58 1 {} 1 9 1 {} 1 72 1 {} 1 33 1 {} 1 75 1 {} 1 81 1 {} 1 23 1 {} 1 13 1 {} 1 14 1 {} 1 91 1 {} 1 91 1 {} 1 15 1 {} 1 36 1 {} 1 3 1 {} 1 69 1 {} 1 52 1 {} 1 50 1 {} 1 10 1 {} 1 33 1 {} 1 39 1 {} 1 58 1 {} 1 38 1 {} 1 83 1 {} 1 82 1 {} 1 7 1 {}} + +do_execsql_test 1.3.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {}} + +do_execsql_test 1.3.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {}} + +do_execsql_test 1.3.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 89 1 6 1 29 1 47 1 59 1 28 1 75 1 78 1 72 1 98 1 87 1 73 1 96 1 74 1 90 1 75 1 91 1 69 1 39 1 7 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 74 1 96 1 97 1 84 1 86 1 32 1 25 1 89 1 29 1 9 1 21 1 12 1 88 1 55 1 70 1 58 1 81 1 91 1 52 1 58 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 74 1 38 1 46 1 23 1 61 1 3 1 1 1 76 1 63 1 73 1 65 1 20 1 8 1 77 1 19 1 9 1 23 1 15 1 50 1 38 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 99 1 39 1 54 1 16 1 85 1 22 1 40 1 4 1 87 1 65 1 5 1 31 1 49 1 2 1 26 1 72 1 13 1 36 1 10 1 83 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 33 1 91 1 8 1 65 1 85 1 55 1 56 1 42 1 80 1 58 1 11 1 95 1 90 1 85 1 47 1 33 1 14 1 3 1 33 1 82 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {}} + +do_execsql_test 1.4.2.1 { + SELECT max(b) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 95 95 84 84 84 84 84 84 84 84 83 83 83 83 83 83 83 83 83 82 82 17 7 5} + +do_execsql_test 1.4.2.2 { + SELECT min(b) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.4.3.1 { + SELECT row_number() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.4.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.4.3.3 { + SELECT row_number() OVER ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.4.4.1 { + SELECT dense_rank() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.4.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.4.4.3 { + SELECT dense_rank() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.4.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.4.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.4.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.4.5.1 { + SELECT rank() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.4.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.4.5.3 { + SELECT rank() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.4.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.4.5.5 { + SELECT rank() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.4.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.4.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.4.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.4.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.4.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206} + +do_execsql_test 1.4.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.4.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.4.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.4.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.4.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.4.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.11.1 { + SELECT first_value(b) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.4.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.4.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99} + +do_execsql_test 1.4.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 10 20 30 30 30 40 50 60 70 80 80 90 90 90 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 2 2 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 8 8 8 28 38 38 58 58 58 58 68 78 78 88 98 98 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99} + +do_execsql_test 1.4.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.4.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.4.12.1 { + SELECT lead(b,b) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.13.1 { + SELECT lag(b,b) OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.4.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.4.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.4.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.4.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.4.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.39.44.58.30.38.34.83.27.82.17.7.5 39.44.58.30.38.34.83.27.82.17.7.5 44.58.30.38.34.83.27.82.17.7.5 58.30.38.34.83.27.82.17.7.5 30.38.34.83.27.82.17.7.5 38.34.83.27.82.17.7.5 34.83.27.82.17.7.5 83.27.82.17.7.5 27.82.17.7.5 82.17.7.5 17.7.5 7.5 5} + +do_execsql_test 1.4.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 90.40.30.80.20.90.60.70.80.90.30.50.10.30 40.30.80.20.90.60.70.80.90.30.50.10.30 30.80.20.90.60.70.80.90.30.50.10.30 80.20.90.60.70.80.90.30.50.10.30 20.90.60.70.80.90.30.50.10.30 90.60.70.80.90.30.50.10.30 60.70.80.90.30.50.10.30 70.80.90.30.50.10.30 80.90.30.50.10.30 90.30.50.10.30 30.50.10.30 50.10.30 10.30 30 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.61.1.21.11.51.41.31.31.11.81.91.91.21 61.1.21.11.51.41.31.31.11.81.91.91.21 1.21.11.51.41.31.31.11.81.91.91.21 21.11.51.41.31.31.11.81.91.91.21 11.51.41.31.31.11.81.91.91.21 51.41.31.31.11.81.91.91.21 41.31.31.11.81.91.91.21 31.31.11.81.91.91.21 31.11.81.91.91.21 11.81.91.91.21 81.91.91.21 91.91.21 91.21 21 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 32.22.42.2.72.12.22.2.72.72.12.62.52.82 22.42.2.72.12.22.2.72.72.12.62.52.82 42.2.72.12.22.2.72.72.12.62.52.82 2.72.12.22.2.72.72.12.62.52.82 72.12.22.2.72.72.12.62.52.82 12.22.2.72.72.12.62.52.82 22.2.72.72.12.62.52.82 2.72.72.12.62.52.82 72.72.12.62.52.82 72.12.62.52.82 12.62.52.82 62.52.82 52.82 82 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 53.63.73.13.73.73.33.93.23.13.33.3.33.83 63.73.13.73.73.33.93.23.13.33.3.33.83 73.13.73.73.33.93.23.13.33.3.33.83 13.73.73.33.93.23.13.33.3.33.83 73.73.33.93.23.13.33.3.33.83 73.33.93.23.13.33.3.33.83 33.93.23.13.33.3.33.83 93.23.13.33.3.33.83 23.13.33.3.33.83 13.33.3.33.83 33.3.33.83 3.33.83 33.83 83 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 94.84.74.34.34.44.74.64.14.34.84.84.44.34 84.74.34.34.44.74.64.14.34.84.84.44.34 74.34.34.44.74.64.14.34.84.84.44.34 34.34.44.74.64.14.34.84.84.44.34 34.44.74.64.14.34.84.84.44.34 44.74.64.14.34.84.84.44.34 74.64.14.34.84.84.44.34 64.14.34.84.84.44.34 14.34.84.84.44.34 34.84.84.44.34 84.84.44.34 84.44.34 44.34 34 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.5.15.95.55.75.85.75.15.95.5 35.5.15.95.55.75.85.75.15.95.5 5.15.95.55.75.85.75.15.95.5 15.95.55.75.85.75.15.95.5 95.55.75.85.75.15.95.5 55.75.85.75.15.95.5 75.85.75.15.95.5 85.75.15.95.5 75.15.95.5 15.95.5 95.5 5 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.16.36.76.96.96.26.26.36.66.36.36 56.16.36.76.96.96.26.26.36.66.36.36 16.36.76.96.96.26.26.36.66.36.36 36.76.96.96.26.26.36.66.36.36 76.96.96.26.26.36.66.36.36 96.96.26.26.36.66.36.36 96.26.26.36.66.36.36 26.26.36.66.36.36 26.36.66.36.36 36.66.36.36 66.36.36 36.36 36 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.87.37.87.77.7.57.47.47.37.27.17.7 87.37.87.77.7.57.47.47.37.27.17.7 37.87.77.7.57.47.47.37.27.17.7 87.77.7.57.47.47.37.27.17.7 77.7.57.47.47.37.27.17.7 7.57.47.47.37.27.17.7 57.47.47.37.27.17.7 47.47.37.27.17.7 47.37.27.17.7 37.27.17.7 27.17.7 17.7 7 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 78.8.28.98.78.58.98.8.88.8.58.58.58.38 8.28.98.78.58.98.8.88.8.58.58.58.38 28.98.78.58.98.8.88.8.58.58.58.38 98.78.58.98.8.88.8.58.58.58.38 78.58.98.8.88.8.58.58.58.38 58.98.8.88.8.58.58.58.38 98.8.88.8.58.58.58.38 8.88.8.58.58.58.38 88.8.58.58.58.38 8.58.58.58.38 58.58.58.38 58.58.38 58.38 38 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39} + +do_execsql_test 1.4.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 94.95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.96.96.96.97.97.98.98.99.99.99 95.96.96.96.97.97.98.98.99.99.99 96.96.96.97.97.98.98.99.99.99 96.96.97.97.98.98.99.99.99 96.97.97.98.98.99.99.99 97.97.98.98.99.99.99 97.98.98.99.99.99 98.98.99.99.99 98.99.99.99 99.99.99 99.99 99} + +do_execsql_test 1.4.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 10.20.30.30.30.40.50.60.70.80.80.90.90.90 20.30.30.30.40.50.60.70.80.80.90.90.90 30.30.30.40.50.60.70.80.80.90.90.90 30.30.40.50.60.70.80.80.90.90.90 30.40.50.60.70.80.80.90.90.90 40.50.60.70.80.80.90.90.90 50.60.70.80.80.90.90.90 60.70.80.80.90.90.90 70.80.80.90.90.90 80.80.90.90.90 80.90.90.90 90.90.90 90.90 90 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.51.61.61.81.81.81.91.91.91.91.91 41.51.61.61.81.81.81.91.91.91.91.91 51.61.61.81.81.81.91.91.91.91.91 61.61.81.81.81.91.91.91.91.91 61.81.81.81.91.91.91.91.91 81.81.81.91.91.91.91.91 81.81.91.91.91.91.91 81.91.91.91.91.91 91.91.91.91.91 91.91.91.91 91.91.91 91.91 91 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 12.12.12.22.22.32.42.52.62.62.72.72.72.82 12.12.22.22.32.42.52.62.62.72.72.72.82 12.22.22.32.42.52.62.62.72.72.72.82 22.22.32.42.52.62.62.72.72.72.82 22.32.42.52.62.62.72.72.72.82 32.42.52.62.62.72.72.72.82 42.52.62.62.72.72.72.82 52.62.62.72.72.72.82 62.62.72.72.72.82 62.72.72.72.82 72.72.72.82 72.72.82 72.82 82 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.43.43.53.63.73.73.73.83.93.93.93 33.43.43.53.63.73.73.73.83.93.93.93 43.43.53.63.73.73.73.83.93.93.93 43.53.63.73.73.73.83.93.93.93 53.63.73.73.73.83.93.93.93 63.73.73.73.83.93.93.93 73.73.73.83.93.93.93 73.73.83.93.93.93 73.83.93.93.93 83.93.93.93 93.93.93 93.93 93 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.54.64.74.74.74.74.74.84.84.84.84.94 54.64.74.74.74.74.74.84.84.84.84.94 64.74.74.74.74.74.84.84.84.84.94 74.74.74.74.74.84.84.84.84.94 74.74.74.74.84.84.84.84.94 74.74.74.84.84.84.84.94 74.74.84.84.84.84.94 74.84.84.84.84.94 84.84.84.84.94 84.84.84.94 84.84.94 84.94 94 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.65.65.65.75.75.75.85.85.85.95.95.95 65.65.65.75.75.75.85.85.85.95.95.95 65.65.75.75.75.85.85.85.95.95.95 65.75.75.75.85.85.85.95.95.95 75.75.75.85.85.85.95.95.95 75.75.85.85.85.95.95.95 75.85.85.85.95.95.95 85.85.85.95.95.95 85.85.95.95.95 85.95.95.95 95.95.95 95.95 95 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.46.46.56.56.56.66.76.86.96.96.96 36.46.46.56.56.56.66.76.86.96.96.96 46.46.56.56.56.66.76.86.96.96.96 46.56.56.56.66.76.86.96.96.96 56.56.56.66.76.86.96.96.96 56.56.66.76.86.96.96.96 56.66.76.86.96.96.96 66.76.86.96.96.96 76.86.96.96.96 86.96.96.96 96.96.96 96.96 96 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.57.67.77.77.87.87.97.97 47.47.57.67.77.77.87.87.97.97 47.57.67.77.77.87.87.97.97 57.67.77.77.87.87.97.97 67.77.77.87.87.97.97 77.77.87.87.97.97 77.87.87.97.97 87.87.97.97 87.97.97 97.97 97 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.28.38.38.58.58.58.58.68.78.78.88.98.98 28.38.38.58.58.58.58.68.78.78.88.98.98 38.38.58.58.58.58.68.78.78.88.98.98 38.58.58.58.58.68.78.78.88.98.98 58.58.58.58.68.78.78.88.98.98 58.58.58.68.78.78.88.98.98 58.58.68.78.78.88.98.98 58.68.78.78.88.98.98 68.78.78.88.98.98 78.78.88.98.98 78.88.98.98 88.98.98 98.98 98 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.49.59.59.59.59.69.79.89.89.89.99.99.99 49.59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.69.79.89.89.89.99.99.99 59.59.69.79.89.89.89.99.99.99 59.69.79.89.89.89.99.99.99 69.79.89.89.89.99.99.99 79.89.89.89.99.99.99 89.89.89.99.99.99 89.89.99.99.99 89.99.99.99 99.99.99 99.99 99} + +do_execsql_test 1.4.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39} + +do_execsql_test 1.4.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.4.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 200 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 199 74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 198 74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 197 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 196 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 195 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 194 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 193 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 192 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 191 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 190 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 189 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 188 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 187 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 186 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 185 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 184 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 183 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 182 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 181 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 180 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 179 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 178 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 177 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 176 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 175 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 174 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 173 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 172 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 171 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 170 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 169 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 168 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 167 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 166 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 165 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 164 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 163 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 162 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 161 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 160 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 159 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 158 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 157 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 156 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 155 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 154 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 153 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 152 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 151 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 150 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 149 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 148 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 147 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 146 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 145 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 144 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 143 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 142 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 141 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 140 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 139 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 138 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 137 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 136 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 135 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 134 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 133 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 132 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 131 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 130 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 129 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 128 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 127 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 126 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 125 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 124 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 123 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 122 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 121 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 120 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 119 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 118 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 117 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 116 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 115 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 114 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 113 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 112 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 111 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 110 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 109 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 108 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 107 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 106 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 105 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 104 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 103 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 102 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 101 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 100 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 99 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 98 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 97 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 96 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 95 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 94 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 93 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 92 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 91 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 90 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 89 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 88 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 87 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 86 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 85 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 84 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 83 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 82 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 81 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 80 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 79 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 78 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 77 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 76 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 75 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 74 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 73 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 72 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 71 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 70 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 69 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 68 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 67 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 66 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 65 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 64 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 63 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 62 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 61 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 60 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 59 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 58 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 57 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 56 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 55 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 54 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 53 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 52 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 51 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 50 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 49 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 48 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 47 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 46 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 45 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 44 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 43 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 42 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 41 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 40 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 39 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 38 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 37 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 36 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 35 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 34 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 33 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 32 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 31 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 30 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 29 15.36.3.69.52.50.10.33.39.58.38.83.82.7 28 15.36.3.69.52.50.10.33.39.58.38.83.82.7 27 36.3.69.52.50.10.33.39.58.38.83.82.7 26 36.3.69.52.50.10.33.39.58.38.83.82.7 25 3.69.52.50.10.33.39.58.38.83.82.7 24 3.69.52.50.10.33.39.58.38.83.82.7 23 69.52.50.10.33.39.58.38.83.82.7 22 69.52.50.10.33.39.58.38.83.82.7 21 52.50.10.33.39.58.38.83.82.7 20 52.50.10.33.39.58.38.83.82.7 19 50.10.33.39.58.38.83.82.7 18 50.10.33.39.58.38.83.82.7 17 10.33.39.58.38.83.82.7 16 10.33.39.58.38.83.82.7 15 33.39.58.38.83.82.7 14 33.39.58.38.83.82.7 13 39.58.38.83.82.7 12 39.58.38.83.82.7 11 58.38.83.82.7 10 58.38.83.82.7 9 38.83.82.7 8 38.83.82.7 7 83.82.7 6 83.82.7 5 82.7 4 82.7 3 7 2 7 1 {}} + +do_execsql_test 1.4.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {201 {} 200 {} 199 {} 198 {} 197 {} 196 {} 195 {} 194 {} 193 {} 192 {} 191 {} 190 {} 189 {} 188 {} 187 {} 186 {} 185 {} 184 {} 183 {} 182 {} 181 {} 180 {} 179 {} 178 {} 177 {} 176 {} 175 {} 174 {} 173 {} 172 {} 171 {} 170 {} 169 {} 168 {} 167 {} 166 {} 165 {} 164 {} 163 {} 162 {} 161 {} 160 {} 159 {} 158 {} 157 {} 156 {} 155 {} 154 {} 153 {} 152 {} 151 {} 150 {} 149 {} 148 {} 147 {} 146 {} 145 {} 144 {} 143 {} 142 {} 141 {} 140 {} 139 {} 138 {} 137 {} 136 {} 135 {} 134 {} 133 {} 132 {} 131 {} 130 {} 129 {} 128 {} 127 {} 126 {} 125 {} 124 {} 123 {} 122 {} 121 {} 120 {} 119 {} 118 {} 117 {} 116 {} 115 {} 114 {} 113 {} 112 {} 111 {} 110 {} 109 {} 108 {} 107 {} 106 {} 105 {} 104 {} 103 {} 102 {} 101 {} 100 {} 99 {} 98 {} 97 {} 96 {} 95 {} 94 {} 93 {} 92 {} 91 {} 90 {} 89 {} 88 {} 87 {} 86 {} 85 {} 84 {} 83 {} 82 {} 81 {} 80 {} 79 {} 78 {} 77 {} 76 {} 75 {} 74 {} 73 {} 72 {} 71 {} 70 {} 69 {} 68 {} 67 {} 66 {} 65 {} 64 {} 63 {} 62 {} 61 {} 60 {} 59 {} 58 {} 57 {} 56 {} 55 {} 54 {} 53 {} 52 {} 51 {} 50 {} 49 {} 48 {} 47 {} 46 {} 45 {} 44 {} 43 {} 42 {} 41 {} 40 {} 39 {} 38 {} 37 {} 36 {} 35 {} 34 {} 33 {} 32 {} 31 {} 30 {} 29 {} 28 {} 27 {} 26 {} 25 {} 24 {} 23 {} 22 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.4.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.4.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 19 6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 18 29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 17 47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 16 59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 15 28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 14 75.78.72.98.87.73.96.74.90.75.91.69.39.7 13 78.72.98.87.73.96.74.90.75.91.69.39.7 12 72.98.87.73.96.74.90.75.91.69.39.7 11 98.87.73.96.74.90.75.91.69.39.7 10 87.73.96.74.90.75.91.69.39.7 9 73.96.74.90.75.91.69.39.7 8 96.74.90.75.91.69.39.7 7 74.90.75.91.69.39.7 6 90.75.91.69.39.7 5 75.91.69.39.7 4 91.69.39.7 3 69.39.7 2 39.7 1 7 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 19 96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 18 97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 17 84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 16 86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 15 32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 14 25.89.29.9.21.12.88.55.70.58.81.91.52.58 13 89.29.9.21.12.88.55.70.58.81.91.52.58 12 29.9.21.12.88.55.70.58.81.91.52.58 11 9.21.12.88.55.70.58.81.91.52.58 10 21.12.88.55.70.58.81.91.52.58 9 12.88.55.70.58.81.91.52.58 8 88.55.70.58.81.91.52.58 7 55.70.58.81.91.52.58 6 70.58.81.91.52.58 5 58.81.91.52.58 4 81.91.52.58 3 91.52.58 2 52.58 1 58 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 19 38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 18 46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 17 23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 16 61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 15 3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 14 1.76.63.73.65.20.8.77.19.9.23.15.50.38 13 76.63.73.65.20.8.77.19.9.23.15.50.38 12 63.73.65.20.8.77.19.9.23.15.50.38 11 73.65.20.8.77.19.9.23.15.50.38 10 65.20.8.77.19.9.23.15.50.38 9 20.8.77.19.9.23.15.50.38 8 8.77.19.9.23.15.50.38 7 77.19.9.23.15.50.38 6 19.9.23.15.50.38 5 9.23.15.50.38 4 23.15.50.38 3 15.50.38 2 50.38 1 38 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 19 39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 18 54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 17 16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 16 85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 15 22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 14 40.4.87.65.5.31.49.2.26.72.13.36.10.83 13 4.87.65.5.31.49.2.26.72.13.36.10.83 12 87.65.5.31.49.2.26.72.13.36.10.83 11 65.5.31.49.2.26.72.13.36.10.83 10 5.31.49.2.26.72.13.36.10.83 9 31.49.2.26.72.13.36.10.83 8 49.2.26.72.13.36.10.83 7 2.26.72.13.36.10.83 6 26.72.13.36.10.83 5 72.13.36.10.83 4 13.36.10.83 3 36.10.83 2 10.83 1 83 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 19 91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 18 8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 17 65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 16 85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 15 55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 14 56.42.80.58.11.95.90.85.47.33.14.3.33.82 13 42.80.58.11.95.90.85.47.33.14.3.33.82 12 80.58.11.95.90.85.47.33.14.3.33.82 11 58.11.95.90.85.47.33.14.3.33.82 10 11.95.90.85.47.33.14.3.33.82 9 95.90.85.47.33.14.3.33.82 8 90.85.47.33.14.3.33.82 7 85.47.33.14.3.33.82 6 47.33.14.3.33.82 5 33.14.3.33.82 4 14.3.33.82 3 3.33.82 2 33.82 1 82 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.5.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 74 74 74 74 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.5.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.5.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.5.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.5.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.5.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.5.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.5.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.5.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.5.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.5.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.5.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.5.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.5.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.5.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.5.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.5.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.5.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.5.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.5.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.5.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 1 76 44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224} + +do_execsql_test 1.5.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 1 147 106 109 168 134 218 191 212 229 240 {} {} {} {} 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 {} {} {} {} 11 79 63 84 78 120 87 162 124 141 138 227 228 {} {} {} {} 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 {} {} {} {} 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 {} {} {} {} 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 {} {} {} {} 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 {} {} {} {} 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 {} {} {} {} 52 83 103 36 88 171 158 156 198 121 210 132 {} {} {} {} 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163} + +do_execsql_test 1.5.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 1 65 102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171} + +do_execsql_test 1.5.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 1 196 134 109 213 223 106 234 191 212 168 {} {} {} {} 65 102 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 {} {} {} {} 11 87 138 63 124 179 78 141 84 120 234 79 231 {} {} {} {} 57 181 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 {} {} {} {} 80 182 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 {} {} {} {} 111 206 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 {} {} {} {} 26 51 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 {} {} {} {} 48 144 207 216 50 224 124 202 87 110 195 200 196 96 110 211 {} {} {} {} 36 121 132 88 52 232 156 210 239 250 83 103 {} {} {} {} 101 163 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150} + +do_execsql_test 1.5.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163} + +do_execsql_test 1.5.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} 41 {} {} {} {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} 2 {} {} {} {} {} 46 62 62 {} {} {} {} 33 {} {} {} {} {} 78 {} 61 {} 59 77 {} 74 {} 27 {} {} 39 67 {} 54 85 74 90 7 61 90 62 {} 93 {} {} {} {} 23 {} 74 93 {} 23 29 3 1 41 {} 65 33 2 98 86 89 25 76 {} 40 38 15 {} {} 74 97 81 40 16 99 76 96 32 80 86 59 2 99 84 84 39 65 27 76 78 84 16 2 96 59 16 41 28 13 89 22 4 42 91 41 33 87 55 81 29 36 28 6 47 97 97 85 33 41 93 15 85 89 98 98 43 23 73 4 56 29 89 46 65 38 59 68 47 9 93 9 23 39 16 93 98 74 65 75 15 56 93 12 2 81 2 23 97 47 91 15 93 35 16 63 8 53 91 33 99} + +do_execsql_test 1.5.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 81 {} {} {} {} {} {} 21 {} {} {} {} {} {} {} {} {} {} 12 {} {} {} 12 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 73 {} 23 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 15 {} {} {} {} {} {} 55 {} 15 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} {} 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 29 29 {} {} {}} + +do_execsql_test 1.5.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} {} {} {} 2 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 8 9 9 10 10 11 11 11 11 11 12 12 12 12 12 13 13 13 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 25 25 25 25 26 26 27 27 28 29 29 29 29 29 29 30 30 30 30 30 30 30 30 30 31 31 31 32 32 33 33 33 33 33 33 33 34 34 34 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 36 37 37 37 38 38 38 38 38 39 39 39 39 39 39 40 40 40 41 41 41 41 42 42 42 43 43 43 43 43 43 43 43 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 47 47} + +do_execsql_test 1.5.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} 90 1 30 {} {} {} {} 30 {} {} {} 1 40 {} 50 11 81 {} 40 {} 50 81 40 {} {} 50 {} {} {} 41 81 {} 41 {} 2 30 2 81 82 {} {} 10 {} {} 81 {} 41 10 81 30 81 {} {} 3 23 {} 3 61 80 {} {} 3 91 91 72 3 63 30 91 94 94 72 91 73 91 84 84 33 41 1 33 84 73 73 91 20 41 84 33 33 84 33 41 84 20 21 44 22 90 22 81 81 74 93 93 93 81 21 83 44 44 21 21 21 13 21 21 34 11 34 73 74 2 60 2 34 2 34 74 60 23 2 2 2 11 91 60 62 73 74 70 51 65 74 93 65 70 34 70 93 93 93 62 35 44 43 12 35 41 43 44 44 41 80 54 72 43 41 43 91 12 80 80 35 33 12} + +do_execsql_test 1.5.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.5.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} 0 0 0 0 0 0 0 0 0 0 0 {} {} {} {} 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 {} {} {} {} 2 2 2 2 2 2 2 2 2 2 2 2 2 {} {} {} {} 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 {} {} {} {} 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 {} {} {} {} 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 {} {} {} {} 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 {} {} {} {} 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 {} {} {} {} 38 38 38 38 38 38 38 38 38 38 38 38 {} {} {} {} 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.5.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.5.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 0 0 0 0 0 0 0 0 0 0 {} {} {} {} 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 {} {} {} {} 2 2 2 2 2 2 2 2 2 2 2 2 2 {} {} {} {} 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 {} {} {} {} 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 {} {} {} {} 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 {} {} {} {} 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 {} {} {} {} 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 {} {} {} {} 8 8 8 8 8 8 8 8 8 8 8 8 {} {} {} {} 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9} + +do_execsql_test 1.5.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.5.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.5.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.5.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.5.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.5.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} 0 0.74 0.74.41 0.74.41.74 0.74.41.74.23 0.74.41.74.23.99 0.74.41.74.23.99.26 0.74.41.74.23.99.26.33 0.74.41.74.23.99.26.33.2 0.74.41.74.23.99.26.33.2.89 0.74.41.74.23.99.26.33.2.89.81 0.74.41.74.23.99.26.33.2.89.81.96 0.74.41.74.23.99.26.33.2.89.81.96.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27} + +do_execsql_test 1.5.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} 0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 {} {} {} {} 41 41.81 41.81.91 41.81.91.61 41.81.91.61.91 41.81.91.61.91.91 41.81.91.61.91.91.1 41.81.91.61.91.91.1.81 41.81.91.61.91.91.1.81.41 41.81.91.61.91.91.1.81.41.61 41.81.91.61.91.91.1.81.41.61.1 41.81.91.61.91.91.1.81.41.61.1.21 41.81.91.61.91.91.1.81.41.61.1.21.11 41.81.91.61.91.91.1.81.41.61.1.21.11.51 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 {} {} {} {} 2 2.62 2.62.12 2.62.12.32 2.62.12.32.22 2.62.12.32.22.42 2.62.12.32.22.42.2 2.62.12.32.22.42.2.72 2.62.12.32.22.42.2.72.12 2.62.12.32.22.42.2.72.12.22 2.62.12.32.22.42.2.72.12.22.2 2.62.12.32.22.42.2.72.12.22.2.72 2.62.12.32.22.42.2.72.12.22.2.72.72 {} {} {} {} 23 23.33 23.33.93 23.33.93.23 23.33.93.23.93 23.33.93.23.93.43 23.33.93.23.93.43.3 23.33.93.23.93.43.3.43 23.33.93.23.93.43.3.43.33 23.33.93.23.93.43.3.43.33.53 23.33.93.23.93.43.3.43.33.53.63 23.33.93.23.93.43.3.43.33.53.63.73 23.33.93.23.93.43.3.43.33.53.63.73.13 23.33.93.23.93.43.3.43.33.53.63.73.13.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 {} {} {} {} 74 74.74 74.74.54 74.74.54.84 74.74.54.84.74 74.74.54.84.74.24 74.74.54.84.74.24.4 74.74.54.84.74.24.4.94 74.74.54.84.74.24.4.94.84 74.74.54.84.74.24.4.94.84.74 74.74.54.84.74.24.4.94.84.74.34 74.74.54.84.74.24.4.94.84.74.34.34 74.74.54.84.74.24.4.94.84.74.34.34.44 74.74.54.84.74.24.4.94.84.74.34.34.44.74 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 {} {} {} {} 65 65.35 65.35.85 65.35.85.85 65.35.85.85.55 65.35.85.85.55.15 65.35.85.85.55.15.25 65.35.85.85.55.15.25.75 65.35.85.85.55.15.25.75.95 65.35.85.85.55.15.25.75.95.65 65.35.85.85.55.15.25.75.95.65.65 65.35.85.85.55.15.25.75.95.65.65.35 65.35.85.85.55.15.25.75.95.65.65.35.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 {} {} {} {} 26 26.96 26.96.46 26.96.46.6 26.96.46.6.46 26.96.46.6.46.16 26.96.46.6.46.16.16 26.96.46.6.46.16.16.86 26.96.46.6.46.16.16.86.56 26.96.46.6.46.16.16.86.56.56 26.96.46.6.46.16.16.86.56.56.56 26.96.46.6.46.16.16.86.56.56.56.16 26.96.46.6.46.16.16.86.56.56.56.16.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 {} {} {} {} 97 97.27 97.27.97 97.27.97.67 97.27.97.67.77 97.27.97.67.77.47 97.27.97.67.77.47.7 97.27.97.67.77.47.7.47 97.27.97.67.77.47.7.47.87 97.27.97.67.77.47.7.47.87.37 97.27.97.67.77.47.7.47.87.37.87 97.27.97.67.77.47.7.47.87.37.87.77 97.27.97.67.77.47.7.47.87.37.87.77.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 {} {} {} {} 38 38.68 38.68.78 38.68.78.8 38.68.78.8.28 38.68.78.8.28.98 38.68.78.8.28.98.78 38.68.78.8.28.98.78.58 38.68.78.8.28.98.78.58.98 38.68.78.8.28.98.78.58.98.8 38.68.78.8.28.98.78.58.98.8.88 38.68.78.8.28.98.78.58.98.8.88.8 {} {} {} {} 99 99.89 99.89.59 99.89.59.39 99.89.59.39.99 99.89.59.39.99.29 99.89.59.39.99.29.59 99.89.59.39.99.29.59.89 99.89.59.39.99.29.59.89.89 99.89.59.39.99.29.59.89.89.29 99.89.59.39.99.29.59.89.89.29.9 99.89.59.39.99.29.59.89.89.29.9.79 99.89.59.39.99.29.59.89.89.29.9.79.49 99.89.59.39.99.29.59.89.89.29.9.79.49.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9} + +do_execsql_test 1.5.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 0.1 0.1.1 0.1.1.2 0.1.1.2.2 0.1.1.2.2.2 0.1.1.2.2.2.3 0.1.1.2.2.2.3.3 0.1.1.2.2.2.3.3.4 0.1.1.2.2.2.3.3.4.5 0.1.1.2.2.2.3.3.4.5.5 0.1.1.2.2.2.3.3.4.5.5.6 0.1.1.2.2.2.3.3.4.5.5.6.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98} + +do_execsql_test 1.5.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 0.10 0.10.20 0.10.20.30 0.10.20.30.30 0.10.20.30.30.30 0.10.20.30.30.30.40 0.10.20.30.30.30.40.50 0.10.20.30.30.30.40.50.60 0.10.20.30.30.30.40.50.60.70 0.10.20.30.30.30.40.50.60.70.80 {} {} {} {} 1 1.1 1.1.11 1.1.11.11 1.1.11.11.21 1.1.11.11.21.21 1.1.11.11.21.21.31 1.1.11.11.21.21.31.31 1.1.11.11.21.21.31.31.41 1.1.11.11.21.21.31.31.41.41 1.1.11.11.21.21.31.31.41.41.41 1.1.11.11.21.21.31.31.41.41.41.51 1.1.11.11.21.21.31.31.41.41.41.51.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91 {} {} {} {} 2 2.2 2.2.2 2.2.2.12 2.2.2.12.12 2.2.2.12.12.12 2.2.2.12.12.12.22 2.2.2.12.12.12.22.22 2.2.2.12.12.12.22.22.32 2.2.2.12.12.12.22.22.32.42 2.2.2.12.12.12.22.22.32.42.52 2.2.2.12.12.12.22.22.32.42.52.62 2.2.2.12.12.12.22.22.32.42.52.62.62 {} {} {} {} 3 3.3 3.3.13 3.3.13.13 3.3.13.13.23 3.3.13.13.23.23 3.3.13.13.23.23.23 3.3.13.13.23.23.23.33 3.3.13.13.23.23.23.33.33 3.3.13.13.23.23.23.33.33.33 3.3.13.13.23.23.23.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73 {} {} {} {} 4 4.14 4.14.24 4.14.24.34 4.14.24.34.34 4.14.24.34.34.34 4.14.24.34.34.34.34 4.14.24.34.34.34.34.44 4.14.24.34.34.34.34.44.44 4.14.24.34.34.34.34.44.44.54 4.14.24.34.34.34.34.44.44.54.64 4.14.24.34.34.34.34.44.44.54.64.74 4.14.24.34.34.34.34.44.44.54.64.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84 {} {} {} {} 5 5.5 5.5.15 5.5.15.15 5.5.15.15.15 5.5.15.15.15.25 5.5.15.15.15.25.35 5.5.15.15.15.25.35.35 5.5.15.15.15.25.35.35.55 5.5.15.15.15.25.35.35.55.55 5.5.15.15.15.25.35.35.55.55.65 5.5.15.15.15.25.35.35.55.55.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85 {} {} {} {} 6 6.16 6.16.16 6.16.16.16 6.16.16.16.26 6.16.16.16.26.26 6.16.16.16.26.26.26 6.16.16.16.26.26.26.36 6.16.16.16.26.26.26.36.36 6.16.16.16.26.26.26.36.36.36 6.16.16.16.26.26.26.36.36.36.36 6.16.16.16.26.26.26.36.36.36.36.46 6.16.16.16.26.26.26.36.36.36.36.46.46 6.16.16.16.26.26.26.36.36.36.36.46.46.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76 {} {} {} {} 7 7.7 7.7.7 7.7.7.17 7.7.7.17.27 7.7.7.17.27.27 7.7.7.17.27.27.37 7.7.7.17.27.27.37.37 7.7.7.17.27.27.37.37.47 7.7.7.17.27.27.37.37.47.47 7.7.7.17.27.27.37.37.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47.57 7.7.7.17.27.27.37.37.47.47.47.47.57.67 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77 {} {} {} {} 8 8.8 8.8.8 8.8.8.28 8.8.8.28.38 8.8.8.28.38.38 8.8.8.28.38.38.58 8.8.8.28.38.38.58.58 8.8.8.28.38.38.58.58.58 8.8.8.28.38.38.58.58.58.58 8.8.8.28.38.38.58.58.58.58.68 8.8.8.28.38.38.58.58.58.58.68.78 {} {} {} {} 9 9.9 9.9.9 9.9.9.19 9.9.9.19.29 9.9.9.19.29.29 9.9.9.19.29.29.29 9.9.9.19.29.29.29.39 9.9.9.19.29.29.29.39.39 9.9.9.19.29.29.29.39.39.39 9.9.9.19.29.29.29.39.39.39.49 9.9.9.19.29.29.29.39.39.39.49.59 9.9.9.19.29.29.29.39.39.39.49.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89} + +do_execsql_test 1.5.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING ) FROM t2 +} {{} {} {} {} 0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 0.90.40.30.80.20.90.60.70.80.90.30 0.90.40.30.80.20.90.60.70.80.90.30.50 0.90.40.30.80.20.90.60.70.80.90.30.50.10 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9} + +do_execsql_test 1.5.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.5.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) +} {0 {} 0 {} 0 {} 0 {} 1 {} 2 74 3 74 4 74.74 5 74.74 6 74.74.99 7 74.74.99 8 74.74.99.33 9 74.74.99.33 10 74.74.99.33.89 11 74.74.99.33.89 12 74.74.99.33.89.96 13 74.74.99.33.89.96 14 74.74.99.33.89.96.38 15 74.74.99.33.89.96.38 16 74.74.99.33.89.96.38.39 17 74.74.99.33.89.96.38.39 18 74.74.99.33.89.96.38.39.91 19 74.74.99.33.89.96.38.39.91 20 74.74.99.33.89.96.38.39.91.6 21 74.74.99.33.89.96.38.39.91.6 22 74.74.99.33.89.96.38.39.91.6.97 23 74.74.99.33.89.96.38.39.91.6.97 24 74.74.99.33.89.96.38.39.91.6.97.46 25 74.74.99.33.89.96.38.39.91.6.97.46 26 74.74.99.33.89.96.38.39.91.6.97.46.54 27 74.74.99.33.89.96.38.39.91.6.97.46.54 28 74.74.99.33.89.96.38.39.91.6.97.46.54.8 29 74.74.99.33.89.96.38.39.91.6.97.46.54.8 30 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 31 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 32 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 33 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 34 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 35 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 36 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 37 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 38 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 39 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 40 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 41 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 42 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 43 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 44 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 45 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 46 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 47 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 48 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 49 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 50 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 51 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 52 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 53 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 54 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 55 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 56 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 57 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 58 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 59 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 60 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 61 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 62 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 63 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 64 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 65 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 66 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 67 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 68 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 69 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 70 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 71 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 72 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 73 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 74 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 75 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 76 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 77 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 78 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 79 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 80 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 81 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 82 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 83 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 84 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 85 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 86 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 87 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 88 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 89 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 90 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 91 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 92 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 93 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 94 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 95 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 96 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 97 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 98 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 99 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 100 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 101 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 102 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 103 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 104 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 105 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 106 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 107 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 108 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 109 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 110 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 111 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 112 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 113 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 114 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 115 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 116 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 117 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 118 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 119 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 120 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 121 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 122 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 123 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 124 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 125 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 126 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 127 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 128 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 129 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 130 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 131 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 132 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 133 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 134 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 135 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 136 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 137 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 138 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 139 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 140 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 141 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 142 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 143 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 144 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 145 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 146 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 147 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 148 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 149 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 150 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 151 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 152 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 153 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 154 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 155 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 156 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 157 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 158 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 159 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 160 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 161 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 162 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 163 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 164 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 165 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 166 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 167 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 168 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 169 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 170 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 171 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 172 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 173 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 174 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 175 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 176 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 177 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 178 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 179 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 180 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 181 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 182 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 183 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 184 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 185 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 186 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 187 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 188 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 189 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 190 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 191 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 192 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 193 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 194 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 195 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 196 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83 197 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83} + +do_execsql_test 1.5.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) +} {0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 21 {} 22 {} 23 {} 24 {} 25 {} 26 {} 27 {} 28 {} 29 {} 30 {} 31 {} 32 {} 33 {} 34 {} 35 {} 36 {} 37 {} 38 {} 39 {} 40 {} 41 {} 42 {} 43 {} 44 {} 45 {} 46 {} 47 {} 48 {} 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 {}} + +do_execsql_test 1.5.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) +} {0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {}} + +do_execsql_test 1.5.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING) +} {0 {} 0 {} 0 {} 0 {} 1 89 2 89.6 3 89.6.29 4 89.6.29.47 5 89.6.29.47.59 6 89.6.29.47.59.28 7 89.6.29.47.59.28.75 8 89.6.29.47.59.28.75.78 9 89.6.29.47.59.28.75.78.72 10 89.6.29.47.59.28.75.78.72.98 11 89.6.29.47.59.28.75.78.72.98.87 12 89.6.29.47.59.28.75.78.72.98.87.73 13 89.6.29.47.59.28.75.78.72.98.87.73.96 14 89.6.29.47.59.28.75.78.72.98.87.73.96.74 15 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90 16 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 0 {} 0 {} 0 {} 0 {} 1 74 2 74.96 3 74.96.97 4 74.96.97.84 5 74.96.97.84.86 6 74.96.97.84.86.32 7 74.96.97.84.86.32.25 8 74.96.97.84.86.32.25.89 9 74.96.97.84.86.32.25.89.29 10 74.96.97.84.86.32.25.89.29.9 11 74.96.97.84.86.32.25.89.29.9.21 12 74.96.97.84.86.32.25.89.29.9.21.12 13 74.96.97.84.86.32.25.89.29.9.21.12.88 14 74.96.97.84.86.32.25.89.29.9.21.12.88.55 15 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70 16 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 74 2 74.38 3 74.38.46 4 74.38.46.23 5 74.38.46.23.61 6 74.38.46.23.61.3 7 74.38.46.23.61.3.1 8 74.38.46.23.61.3.1.76 9 74.38.46.23.61.3.1.76.63 10 74.38.46.23.61.3.1.76.63.73 11 74.38.46.23.61.3.1.76.63.73.65 12 74.38.46.23.61.3.1.76.63.73.65.20 13 74.38.46.23.61.3.1.76.63.73.65.20.8 14 74.38.46.23.61.3.1.76.63.73.65.20.8.77 15 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19 16 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 99 2 99.39 3 99.39.54 4 99.39.54.16 5 99.39.54.16.85 6 99.39.54.16.85.22 7 99.39.54.16.85.22.40 8 99.39.54.16.85.22.40.4 9 99.39.54.16.85.22.40.4.87 10 99.39.54.16.85.22.40.4.87.65 11 99.39.54.16.85.22.40.4.87.65.5 12 99.39.54.16.85.22.40.4.87.65.5.31 13 99.39.54.16.85.22.40.4.87.65.5.31.49 14 99.39.54.16.85.22.40.4.87.65.5.31.49.2 15 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26 16 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 0 {} 0 {} 0 {} 0 {} 1 33 2 33.91 3 33.91.8 4 33.91.8.65 5 33.91.8.65.85 6 33.91.8.65.85.55 7 33.91.8.65.85.55.56 8 33.91.8.65.85.55.56.42 9 33.91.8.65.85.55.56.42.80 10 33.91.8.65.85.55.56.42.80.58 11 33.91.8.65.85.55.56.42.80.58.11 12 33.91.8.65.85.55.56.42.80.58.11.95 13 33.91.8.65.85.55.56.42.80.58.11.95.90 14 33.91.8.65.85.55.56.42.80.58.11.95.90.85 15 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47 16 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33 0 {} 0 {} 0 {} 0 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {}} + +do_execsql_test 1.6.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 74 74 74 74 99 99 99 33 89 89 96 96 96 68 68 68 91 91 91 99 99 99 97 78 78 97 97 97 67 93 93 93 84 77 23 93 93 93 65 47 86 86 86 91 91 91 85 85 85 59 59 56 56 91 91 91 90 90 55 89 89 89 47 56 56 56 56 56 75 75 89 98 98 98 81 94 94 94 78 78 78 53 63 63 87 87 87 84 84 84 72 61 73 95 95 95 65 96 98 98 98 74 74 74 65 73 73 73 87 87 87 41 20 31 31 31 95 95 95 79 88 88 88 34 49 49 90 90 96 96 96 75 77 77 77 44 85 85 85 74 74 70 70 59 39 39 47 80 90 90 90 58 58 72 72 72 72 93 93 93 81 81 81 37 37 37 14 62 91 91 91 91 91 34 36 99 99 99 95 95 69 58 52 84 84 84 84 84 39 44 58 58 58 38 83 83 83 82} + +do_execsql_test 1.6.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 0 0 41 23 23 23 26 2 2 2 81 59 38 38 38 39 39 46 6 6 6 27 27 27 46 54 8 8 8 29 29 77 23 16 16 16 16 35 35 7 7 7 61 61 61 24 24 24 43 12 12 12 3 3 3 22 22 15 15 15 25 25 1 1 1 40 40 16 16 16 36 36 76 76 4 4 4 30 30 30 29 29 29 2 2 2 37 37 72 41 9 9 9 61 65 13 13 13 58 1 1 1 21 35 5 5 5 11 11 41 12 8 8 8 20 15 15 15 22 22 73 34 8 8 8 11 34 34 59 59 55 55 55 44 2 2 2 7 57 29 29 29 19 19 19 26 26 26 47 36 36 36 9 9 9 66 33 33 33 64 64 9 9 9 13 12 12 12 14 36 36 33 15 15 15 34 3 3 3 58 52 30 30 30 10 10 10 21 21 21 39 30 30 30 34 27 27 17} + +do_execsql_test 1.6.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.6.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.6.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.6.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.6.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.6.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.6.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.6.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.6.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.6.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {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} + +do_execsql_test 1.6.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.6.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.6.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.6.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.6.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.6.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.6.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.6.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.6.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 1 76 44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216} + +do_execsql_test 1.6.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 1 147 106 109 168 134 218 191 212 229 240 213 234 {} {} 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 {} {} 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 {} {} 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 {} {} 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 {} {} 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 {} {} 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 {} {} 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 {} {} 52 83 103 36 88 171 158 156 198 121 210 132 210 239 {} {} 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276} + +do_execsql_test 1.6.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 1 65 102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105} + +do_execsql_test 1.6.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 1 196 134 109 213 223 106 234 191 212 168 229 147 {} {} 65 102 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 {} {} 11 87 138 63 124 179 78 141 84 120 234 79 231 162 227 {} {} 57 181 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 {} {} 80 182 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 {} {} 111 206 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 {} {} 26 51 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 {} {} 48 144 207 216 50 224 124 202 87 110 195 200 196 96 110 211 173 197 {} {} 36 121 132 88 52 232 156 210 239 250 83 103 158 210 {} {} 101 163 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105} + +do_execsql_test 1.6.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276} + +do_execsql_test 1.6.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 77 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 22 {} {} {} 12 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} {} {} 1 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} 91 {} {} {} {} {} 22 {} {} {} 12 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} 0 0 0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27} + +do_execsql_test 1.6.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} 0 0 0 90 40 30 80 20 90 60 70 80 90 {} {} 41 41 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 {} {} 2 2 2 62 12 32 22 42 2 72 12 22 2 72 72 {} {} 23 23 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 {} {} 74 74 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 {} {} 65 65 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 {} {} 26 26 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 {} {} 97 97 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 {} {} 38 38 38 68 78 8 28 98 78 58 98 8 88 8 {} {} 99 99 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.6.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 0 0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98} + +do_execsql_test 1.6.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 0 0 10 20 30 30 30 40 50 60 70 80 {} {} 1 1 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 {} {} 2 2 2 2 2 12 12 12 22 22 32 42 52 62 62 {} {} 3 3 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 {} {} 4 4 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 {} {} 5 5 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 {} {} 6 6 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 {} {} 7 7 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 {} {} 8 8 8 8 8 28 38 38 58 58 58 58 68 78 {} {} 9 9 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89} + +do_execsql_test 1.6.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 0 0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.6.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.6.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.6.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.6.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.6.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} 0 0.74 0.74.41 74.41.74 41.74.23 74.23.99 23.99.26 99.26.33 26.33.2 33.2.89 2.89.81 89.81.96 81.96.59 96.59.38 59.38.68 38.68.39 68.39.62 39.62.91 62.91.46 91.46.6 46.6.99 6.99.97 99.97.27 97.27.46 27.46.78 46.78.54 78.54.97 54.97.8 97.8.67 8.67.29 67.29.93 29.93.84 93.84.77 84.77.23 77.23.16 23.16.16 16.16.93 16.93.65 93.65.35 65.35.47 35.47.7 47.7.86 7.86.74 86.74.61 74.61.91 61.91.85 91.85.24 85.24.85 24.85.43 85.43.59 43.59.12 59.12.32 12.32.56 32.56.3 56.3.91 3.91.22 91.22.90 22.90.55 90.55.15 55.15.28 15.28.89 28.89.25 89.25.47 25.47.1 47.1.56 1.56.40 56.40.43 40.43.56 43.56.16 56.16.75 16.75.36 75.36.89 36.89.98 89.98.76 98.76.81 76.81.4 81.4.94 4.94.42 94.42.30 42.30.78 30.78.33 78.33.29 33.29.53 29.53.63 53.63.2 63.2.87 2.87.37 87.37.80 37.80.84 80.84.72 84.72.41 72.41.9 41.9.61 9.61.73 61.73.95 73.95.65 95.65.13 65.13.58 13.58.96 58.96.98 96.98.1 98.1.21 1.21.74 21.74.65 74.65.35 65.35.5 35.5.73 5.73.11 73.11.51 11.51.87 51.87.41 87.41.12 41.12.8 12.8.20 8.20.31 20.31.31 31.31.15 31.15.95 15.95.22 95.22.73 22.73.79 73.79.88 79.88.34 88.34.8 34.8.11 8.11.49 11.49.34 49.34.90 34.90.59 90.59.96 59.96.60 96.60.55 60.55.75 55.75.77 75.77.44 77.44.2 44.2.7 2.7.85 7.85.57 85.57.74 57.74.29 74.29.70 29.70.59 70.59.19 59.19.39 19.39.26 39.26.26 26.26.47 26.47.80 47.80.90 80.90.36 90.36.58 36.58.47 58.47.9 47.9.72 9.72.72 72.72.66 72.66.33 66.33.93 33.93.75 93.75.64 75.64.81 64.81.9 81.9.23 9.23.37 23.37.13 37.13.12 13.12.14 12.14.62 14.62.91 62.91.36 91.36.91 36.91.33 91.33.15 33.15.34 15.34.36 34.36.99 36.99.3 99.3.95 3.95.69 95.69.58 69.58.52 58.52.30 52.30.50 30.50.84 50.84.10 84.10.84 10.84.33 84.33.21 33.21.39 21.39.44 39.44.58 44.58.30 58.30.38 30.38.34 38.34.83 34.83.27 83.27.82 27.82.17} + +do_execsql_test 1.6.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} 0 0.90 0.90.40 90.40.30 40.30.80 30.80.20 80.20.90 20.90.60 90.60.70 60.70.80 70.80.90 80.90.30 90.30.50 {} {} 41 41.81 41.81.91 81.91.61 91.61.91 61.91.91 91.91.1 91.1.81 1.81.41 81.41.61 41.61.1 61.1.21 1.21.11 21.11.51 11.51.41 51.41.31 41.31.31 31.31.11 31.11.81 11.81.91 {} {} 2 2.62 2.62.12 62.12.32 12.32.22 32.22.42 22.42.2 42.2.72 2.72.12 72.12.22 12.22.2 22.2.72 2.72.72 72.72.12 72.12.62 {} {} 23 23.33 23.33.93 33.93.23 93.23.93 23.93.43 93.43.3 43.3.43 3.43.33 43.33.53 33.53.63 53.63.73 63.73.13 73.13.73 13.73.73 73.73.33 73.33.93 33.93.23 93.23.13 23.13.33 13.33.3 {} {} 74 74.74 74.74.54 74.54.84 54.84.74 84.74.24 74.24.4 24.4.94 4.94.84 94.84.74 84.74.34 74.34.34 34.34.44 34.44.74 44.74.64 74.64.14 64.14.34 14.34.84 34.84.84 {} {} 65 65.35 65.35.85 35.85.85 85.85.55 85.55.15 55.15.25 15.25.75 25.75.95 75.95.65 95.65.65 65.65.35 65.35.5 35.5.15 5.15.95 15.95.55 95.55.75 55.75.85 75.85.75 85.75.15 {} {} 26 26.96 26.96.46 96.46.6 46.6.46 6.46.16 46.16.16 16.16.86 16.86.56 86.56.56 56.56.56 56.56.16 56.16.36 16.36.76 36.76.96 76.96.96 96.96.26 96.26.26 26.26.36 26.36.66 {} {} 97 97.27 97.27.97 27.97.67 97.67.77 67.77.47 77.47.7 47.7.47 7.47.87 47.87.37 87.37.87 37.87.77 87.77.7 77.7.57 7.57.47 57.47.47 47.47.37 47.37.27 {} {} 38 38.68 38.68.78 68.78.8 78.8.28 8.28.98 28.98.78 98.78.58 78.58.98 58.98.8 98.8.88 8.88.8 88.8.58 8.58.58 {} {} 99 99.89 99.89.59 89.59.39 59.39.99 39.99.29 99.29.59 29.59.89 59.89.89 89.89.29 89.29.9 29.9.79 9.79.49 79.49.59 49.59.29 59.29.59 29.59.19 59.19.39 19.39.9 39.9.9 9.9.99} + +do_execsql_test 1.6.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 0.1 0.1.1 1.1.2 1.2.2 2.2.2 2.2.3 2.3.3 3.3.4 3.4.5 4.5.5 5.5.6 5.6.7 6.7.7 7.7.7 7.7.8 7.8.8 8.8.8 8.8.9 8.9.9 9.9.9 9.9.10 9.10.11 10.11.11 11.11.12 11.12.12 12.12.12 12.12.13 12.13.13 13.13.14 13.14.15 14.15.15 15.15.15 15.15.16 15.16.16 16.16.16 16.16.17 16.17.19 17.19.20 19.20.21 20.21.21 21.21.22 21.22.22 22.22.23 22.23.23 23.23.23 23.23.24 23.24.25 24.25.26 25.26.26 26.26.26 26.26.27 26.27.27 27.27.28 27.28.29 28.29.29 29.29.29 29.29.30 29.30.30 30.30.30 30.30.31 30.31.31 31.31.32 31.32.33 32.33.33 33.33.33 33.33.33 33.33.33 33.33.34 33.34.34 34.34.34 34.34.34 34.34.35 34.35.35 35.35.36 35.36.36 36.36.36 36.36.36 36.36.37 36.37.37 37.37.38 37.38.38 38.38.39 38.39.39 39.39.39 39.39.40 39.40.41 40.41.41 41.41.41 41.41.42 41.42.43 42.43.43 43.43.44 43.44.44 44.44.46 44.46.46 46.46.47 46.47.47 47.47.47 47.47.47 47.47.49 47.49.50 49.50.51 50.51.52 51.52.53 52.53.54 53.54.55 54.55.55 55.55.56 55.56.56 56.56.56 56.56.57 56.57.58 57.58.58 58.58.58 58.58.58 58.58.59 58.59.59 59.59.59 59.59.59 59.59.60 59.60.61 60.61.61 61.61.62 61.62.62 62.62.63 62.63.64 63.64.65 64.65.65 65.65.65 65.65.66 65.66.67 66.67.68 67.68.69 68.69.70 69.70.72 70.72.72 72.72.72 72.72.73 72.73.73 73.73.73 73.73.74 73.74.74 74.74.74 74.74.74 74.74.74 74.74.75 74.75.75 75.75.75 75.75.76 75.76.77 76.77.77 77.77.78 77.78.78 78.78.79 78.79.80 79.80.80 80.80.81 80.81.81 81.81.81 81.81.82 81.82.83 82.83.84 83.84.84 84.84.84 84.84.84 84.84.85 84.85.85 85.85.85 85.85.86 85.86.87 86.87.87 87.87.88 87.88.89 88.89.89 89.89.89 89.89.90 89.90.90 90.90.90 90.90.91 90.91.91 91.91.91 91.91.91 91.91.91 91.91.93 91.93.93 93.93.93 93.93.94 93.94.95 94.95.95 95.95.95 95.95.96 95.96.96 96.96.96 96.96.97 96.97.97 97.97.98 97.98.98 98.98.99} + +do_execsql_test 1.6.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 0.10 0.10.20 10.20.30 20.30.30 30.30.30 30.30.40 30.40.50 40.50.60 50.60.70 60.70.80 70.80.80 80.80.90 {} {} 1 1.1 1.1.11 1.11.11 11.11.21 11.21.21 21.21.31 21.31.31 31.31.41 31.41.41 41.41.41 41.41.51 41.51.61 51.61.61 61.61.81 61.81.81 81.81.81 81.81.91 81.91.91 91.91.91 {} {} 2 2.2 2.2.2 2.2.12 2.12.12 12.12.12 12.12.22 12.22.22 22.22.32 22.32.42 32.42.52 42.52.62 52.62.62 62.62.72 62.72.72 {} {} 3 3.3 3.3.13 3.13.13 13.13.23 13.23.23 23.23.23 23.23.33 23.33.33 33.33.33 33.33.33 33.33.33 33.33.43 33.43.43 43.43.53 43.53.63 53.63.73 63.73.73 73.73.73 73.73.83 73.83.93 {} {} 4 4.14 4.14.24 14.24.34 24.34.34 34.34.34 34.34.34 34.34.44 34.44.44 44.44.54 44.54.64 54.64.74 64.74.74 74.74.74 74.74.74 74.74.74 74.74.84 74.84.84 84.84.84 {} {} 5 5.5 5.5.15 5.15.15 15.15.15 15.15.25 15.25.35 25.35.35 35.35.55 35.55.55 55.55.65 55.65.65 65.65.65 65.65.75 65.75.75 75.75.75 75.75.85 75.85.85 85.85.85 85.85.95 {} {} 6 6.16 6.16.16 16.16.16 16.16.26 16.26.26 26.26.26 26.26.36 26.36.36 36.36.36 36.36.36 36.36.46 36.46.46 46.46.56 46.56.56 56.56.56 56.56.66 56.66.76 66.76.86 76.86.96 {} {} 7 7.7 7.7.7 7.7.17 7.17.27 17.27.27 27.27.37 27.37.37 37.37.47 37.47.47 47.47.47 47.47.47 47.47.57 47.57.67 57.67.77 67.77.77 77.77.87 77.87.87 {} {} 8 8.8 8.8.8 8.8.28 8.28.38 28.38.38 38.38.58 38.58.58 58.58.58 58.58.58 58.58.68 58.68.78 68.78.78 78.78.88 {} {} 9 9.9 9.9.9 9.9.19 9.19.29 19.29.29 29.29.29 29.29.39 29.39.39 39.39.39 39.39.49 39.49.59 49.59.59 59.59.59 59.59.59 59.59.69 59.69.79 69.79.89 79.89.89 89.89.89 89.89.99} + +do_execsql_test 1.6.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING ) FROM t2 +} {{} {} 0 0.90 0.90.40 90.40.30 40.30.80 30.80.20 80.20.90 20.90.60 90.60.70 60.70.80 70.80.90 80.90.30 90.30.50 30.50.10 50.10.30 10.30.41 30.41.81 41.81.91 81.91.61 91.61.91 61.91.91 91.91.1 91.1.81 1.81.41 81.41.61 41.61.1 61.1.21 1.21.11 21.11.51 11.51.41 51.41.31 41.31.31 31.31.11 31.11.81 11.81.91 81.91.91 91.91.21 91.21.2 21.2.62 2.62.12 62.12.32 12.32.22 32.22.42 22.42.2 42.2.72 2.72.12 72.12.22 12.22.2 22.2.72 2.72.72 72.72.12 72.12.62 12.62.52 62.52.82 52.82.23 82.23.33 23.33.93 33.93.23 93.23.93 23.93.43 93.43.3 43.3.43 3.43.33 43.33.53 33.53.63 53.63.73 63.73.13 73.13.73 13.73.73 73.73.33 73.33.93 33.93.23 93.23.13 23.13.33 13.33.3 33.3.33 3.33.83 33.83.74 83.74.74 74.74.54 74.54.84 54.84.74 84.74.24 74.24.4 24.4.94 4.94.84 94.84.74 84.74.34 74.34.34 34.34.44 34.44.74 44.74.64 74.64.14 64.14.34 14.34.84 34.84.84 84.84.44 84.44.34 44.34.65 34.65.35 65.35.85 35.85.85 85.85.55 85.55.15 55.15.25 15.25.75 25.75.95 75.95.65 95.65.65 65.65.35 65.35.5 35.5.15 5.15.95 15.95.55 95.55.75 55.75.85 75.85.75 85.75.15 75.15.95 15.95.5 95.5.26 5.26.96 26.96.46 96.46.6 46.6.46 6.46.16 46.16.16 16.16.86 16.86.56 86.56.56 56.56.56 56.56.16 56.16.36 16.36.76 36.76.96 76.96.96 96.96.26 96.26.26 26.26.36 26.36.66 36.66.36 66.36.36 36.36.97 36.97.27 97.27.97 27.97.67 97.67.77 67.77.47 77.47.7 47.7.47 7.47.87 47.87.37 87.37.87 37.87.77 87.77.7 77.7.57 7.57.47 57.47.47 47.47.37 47.37.27 37.27.17 27.17.7 17.7.38 7.38.68 38.68.78 68.78.8 78.8.28 8.28.98 28.98.78 98.78.58 78.58.98 58.98.8 98.8.88 8.88.8 88.8.58 8.58.58 58.58.58 58.58.38 58.38.99 38.99.89 99.89.59 89.59.39 59.39.99 39.99.29 99.29.59 29.59.89 59.89.89 89.89.29 89.29.9 29.9.79 9.79.49 79.49.59 49.59.29 59.29.59 29.59.19 59.19.39 19.39.9 39.9.9 9.9.99} + +do_execsql_test 1.6.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.6.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) +} {0 {} 0 {} 1 {} 2 74 3 74 3 74.74 3 74 3 74.99 3 99 3 99.33 3 33 3 33.89 3 89 3 89.96 3 96 3 96.38 3 38 3 38.39 3 39 3 39.91 3 91 3 91.6 3 6 3 6.97 3 97 3 97.46 3 46 3 46.54 3 54 3 54.8 3 8 3 8.29 3 29 3 29.84 3 84 3 84.23 3 23 3 23.16 3 16 3 16.65 3 65 3 65.47 3 47 3 47.86 3 86 3 86.61 3 61 3 61.85 3 85 3 85.85 3 85 3 85.59 3 59 3 59.32 3 32 3 32.3 3 3 3 3.22 3 22 3 22.55 3 55 3 55.28 3 28 3 28.25 3 25 3 25.1 3 1 3 1.40 3 40 3 40.56 3 56 3 56.75 3 75 3 75.89 3 89 3 89.76 3 76 3 76.4 3 4 3 4.42 3 42 3 42.78 3 78 3 78.29 3 29 3 29.63 3 63 3 63.87 3 87 3 87.80 3 80 3 80.72 3 72 3 72.9 3 9 3 9.73 3 73 3 73.65 3 65 3 65.58 3 58 3 58.98 3 98 3 98.21 3 21 3 21.65 3 65 3 65.5 3 5 3 5.11 3 11 3 11.87 3 87 3 87.12 3 12 3 12.20 3 20 3 20.31 3 31 3 31.95 3 95 3 95.73 3 73 3 73.88 3 88 3 88.8 3 8 3 8.49 3 49 3 49.90 3 90 3 90.96 3 96 3 96.55 3 55 3 55.77 3 77 3 77.2 3 2 3 2.85 3 85 3 85.74 3 74 3 74.70 3 70 3 70.19 3 19 3 19.26 3 26 3 26.47 3 47 3 47.90 3 90 3 90.58 3 58 3 58.9 3 9 3 9.72 3 72 3 72.33 3 33 3 33.75 3 75 3 75.81 3 81 3 81.23 3 23 3 23.13 3 13 3 13.14 3 14 3 14.91 3 91 3 91.91 3 91 3 91.15 3 15 3 15.36 3 36 3 36.3 3 3 3 3.69 3 69 3 69.52 3 52 3 52.50 3 50 3 50.10 3 10 3 10.33 3 33 3 33.39 3 39 3 39.58 3 58 3 58.38 3 38 3 38.83 3 83 3 83.82 3 82} + +do_execsql_test 1.6.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) +} {0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {}} + +do_execsql_test 1.6.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) +} {0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {}} + +do_execsql_test 1.6.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) +} {0 {} 0 {} 1 89 2 89.6 3 89.6.29 3 6.29.47 3 29.47.59 3 47.59.28 3 59.28.75 3 28.75.78 3 75.78.72 3 78.72.98 3 72.98.87 3 98.87.73 3 87.73.96 3 73.96.74 3 96.74.90 3 74.90.75 3 90.75.91 3 75.91.69 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 74 2 74.96 3 74.96.97 3 96.97.84 3 97.84.86 3 84.86.32 3 86.32.25 3 32.25.89 3 25.89.29 3 89.29.9 3 29.9.21 3 9.21.12 3 21.12.88 3 12.88.55 3 88.55.70 3 55.70.58 3 70.58.81 3 58.81.91 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 74 2 74.38 3 74.38.46 3 38.46.23 3 46.23.61 3 23.61.3 3 61.3.1 3 3.1.76 3 1.76.63 3 76.63.73 3 63.73.65 3 73.65.20 3 65.20.8 3 20.8.77 3 8.77.19 3 77.19.9 3 19.9.23 3 9.23.15 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 99 2 99.39 3 99.39.54 3 39.54.16 3 54.16.85 3 16.85.22 3 85.22.40 3 22.40.4 3 40.4.87 3 4.87.65 3 87.65.5 3 65.5.31 3 5.31.49 3 31.49.2 3 49.2.26 3 2.26.72 3 26.72.13 3 72.13.36 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 0 {} 0 {} 1 33 2 33.91 3 33.91.8 3 91.8.65 3 8.65.85 3 65.85.55 3 85.55.56 3 55.56.42 3 56.42.80 3 42.80.58 3 80.58.11 3 58.11.95 3 11.95.90 3 95.90.85 3 90.85.47 3 85.47.33 3 47.33.14 3 33.14.3 0 {} 0 {} 1 {} 2 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {}} + +do_execsql_test 1.7.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 74 74 74 74 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.7.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.7.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.7.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.7.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.7.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.7.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.7.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.7.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.7.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.7.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.7.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.7.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.7.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.7.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.7.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.7.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.7.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.7.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.7.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.7.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 76 44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206} + +do_execsql_test 1.7.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.7.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 65 102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276} + +do_execsql_test 1.7.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 196 134 109 213 223 106 234 191 212 168 229 147 218 240 65 102 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 11 87 138 63 124 179 78 141 84 120 234 79 231 162 227 228 280 57 181 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 80 182 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 111 206 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 26 51 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 48 144 207 216 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 36 121 132 88 52 232 156 210 239 250 83 103 158 210 171 198 101 163 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276} + +do_execsql_test 1.7.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.7.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.7.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 41 {} {} {} {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} 2 {} 29 {} {} {} 46 62 62 {} {} 16 {} 33 {} {} {} {} {} 78 {} 61 {} 59 77 {} 74 {} 27 {} 22 39 67 {} 54 85 74 90 7 61 90 62 {} 93 {} {} {} {} 23 {} 74 93 30 23 29 3 1 41 {} 65 33 2 98 86 89 25 76 {} 40 38 15 13 96 74 97 81 40 16 99 76 96 32 80 86 59 2 99 84 84 39 65 27 76 78 84 16 2 96 59 16 41 28 13 89 22 4 42 91 41 33 87 55 81 29 36 28 6 47 97 97 85 33 41 93 15 85 89 98 98 43 23 73 4 56 29 89 46 65 38 59 68 47 9 93 9 23 39 16 93 98 74 65 75 15 56 93 12 2 81 2 23 97 47 91 15 93 35 16 63 8 53 91 33 99} + +do_execsql_test 1.7.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 81 {} {} {} 81 {} 21 {} {} {} {} 21 {} {} {} 21 {} {} {} {} {} {} 12 {} {} {} 12 {} {} 72 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 73 {} 23 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 15 {} {} {} {} {} {} 55 {} 15 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 47 {} {} {} {} {} {} {} {} {} 98 {} 98 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 29 {} {} {} {} {} {} {} 29 29 {} {} {}} + +do_execsql_test 1.7.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 8 9 9 10 10 11 11 11 11 11 12 12 12 12 12 13 13 13 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 25 25 25 25 26 26 27 27 28 29 29 29 29 29 29 30 30 30 30 30 30 30 30 30 31 31 31 32 32 33 33 33 33 33 33 33 34 34 34 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 36 37 37 37 38 38 38 38 38 39 39 39 39 39 39 40 40 40 41 41 41 41 42 42 42 43 43 43 43 43 43 43 43 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 47 47} + +do_execsql_test 1.7.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 90 {} {} {} 90 1 30 {} {} {} 31 30 {} {} {} 1 40 {} 50 11 81 42 40 {} 50 81 40 {} {} 50 {} 52 {} 41 81 {} 41 {} 2 30 2 81 82 53 {} 10 {} {} 81 {} 41 10 81 30 81 {} 3 3 23 {} 3 61 80 {} 94 3 91 91 72 3 63 30 91 94 94 72 91 73 91 84 84 33 41 1 33 84 73 73 91 20 41 84 33 33 84 33 41 84 20 21 44 22 90 22 81 81 74 93 93 93 81 21 83 44 44 21 21 21 13 21 21 34 11 34 73 74 2 60 2 34 2 34 74 60 23 2 2 2 11 91 60 62 73 74 70 51 65 74 93 65 70 34 70 93 93 93 62 35 44 43 12 35 41 43 44 44 41 80 54 72 43 41 43 91 12 80 80 35 33 12} + +do_execsql_test 1.7.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.7.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.7.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.7.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9} + +do_execsql_test 1.7.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.7.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.7.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.7.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.7.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.7.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.7.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.7.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0.74 0.74.41 0.74.41.74 0.74.41.74.23 0.74.41.74.23.99 0.74.41.74.23.99.26 0.74.41.74.23.99.26.33 0.74.41.74.23.99.26.33.2 0.74.41.74.23.99.26.33.2.89 0.74.41.74.23.99.26.33.2.89.81 0.74.41.74.23.99.26.33.2.89.81.96 0.74.41.74.23.99.26.33.2.89.81.96.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5} + +do_execsql_test 1.7.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 0.90.40.30.80.20.90.60.70.80.90.30 0.90.40.30.80.20.90.60.70.80.90.30.50 0.90.40.30.80.20.90.60.70.80.90.30.50.10 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 41 41.81 41.81.91 41.81.91.61 41.81.91.61.91 41.81.91.61.91.91 41.81.91.61.91.91.1 41.81.91.61.91.91.1.81 41.81.91.61.91.91.1.81.41 41.81.91.61.91.91.1.81.41.61 41.81.91.61.91.91.1.81.41.61.1 41.81.91.61.91.91.1.81.41.61.1.21 41.81.91.61.91.91.1.81.41.61.1.21.11 41.81.91.61.91.91.1.81.41.61.1.21.11.51 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 2 2.62 2.62.12 2.62.12.32 2.62.12.32.22 2.62.12.32.22.42 2.62.12.32.22.42.2 2.62.12.32.22.42.2.72 2.62.12.32.22.42.2.72.12 2.62.12.32.22.42.2.72.12.22 2.62.12.32.22.42.2.72.12.22.2 2.62.12.32.22.42.2.72.12.22.2.72 2.62.12.32.22.42.2.72.12.22.2.72.72 2.62.12.32.22.42.2.72.12.22.2.72.72.12 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 23 23.33 23.33.93 23.33.93.23 23.33.93.23.93 23.33.93.23.93.43 23.33.93.23.93.43.3 23.33.93.23.93.43.3.43 23.33.93.23.93.43.3.43.33 23.33.93.23.93.43.3.43.33.53 23.33.93.23.93.43.3.43.33.53.63 23.33.93.23.93.43.3.43.33.53.63.73 23.33.93.23.93.43.3.43.33.53.63.73.13 23.33.93.23.93.43.3.43.33.53.63.73.13.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 74 74.74 74.74.54 74.74.54.84 74.74.54.84.74 74.74.54.84.74.24 74.74.54.84.74.24.4 74.74.54.84.74.24.4.94 74.74.54.84.74.24.4.94.84 74.74.54.84.74.24.4.94.84.74 74.74.54.84.74.24.4.94.84.74.34 74.74.54.84.74.24.4.94.84.74.34.34 74.74.54.84.74.24.4.94.84.74.34.34.44 74.74.54.84.74.24.4.94.84.74.34.34.44.74 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 65 65.35 65.35.85 65.35.85.85 65.35.85.85.55 65.35.85.85.55.15 65.35.85.85.55.15.25 65.35.85.85.55.15.25.75 65.35.85.85.55.15.25.75.95 65.35.85.85.55.15.25.75.95.65 65.35.85.85.55.15.25.75.95.65.65 65.35.85.85.55.15.25.75.95.65.65.35 65.35.85.85.55.15.25.75.95.65.65.35.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 26 26.96 26.96.46 26.96.46.6 26.96.46.6.46 26.96.46.6.46.16 26.96.46.6.46.16.16 26.96.46.6.46.16.16.86 26.96.46.6.46.16.16.86.56 26.96.46.6.46.16.16.86.56.56 26.96.46.6.46.16.16.86.56.56.56 26.96.46.6.46.16.16.86.56.56.56.16 26.96.46.6.46.16.16.86.56.56.56.16.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 97 97.27 97.27.97 97.27.97.67 97.27.97.67.77 97.27.97.67.77.47 97.27.97.67.77.47.7 97.27.97.67.77.47.7.47 97.27.97.67.77.47.7.47.87 97.27.97.67.77.47.7.47.87.37 97.27.97.67.77.47.7.47.87.37.87 97.27.97.67.77.47.7.47.87.37.87.77 97.27.97.67.77.47.7.47.87.37.87.77.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 38 38.68 38.68.78 38.68.78.8 38.68.78.8.28 38.68.78.8.28.98 38.68.78.8.28.98.78 38.68.78.8.28.98.78.58 38.68.78.8.28.98.78.58.98 38.68.78.8.28.98.78.58.98.8 38.68.78.8.28.98.78.58.98.8.88 38.68.78.8.28.98.78.58.98.8.88.8 38.68.78.8.28.98.78.58.98.8.88.8.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 99 99.89 99.89.59 99.89.59.39 99.89.59.39.99 99.89.59.39.99.29 99.89.59.39.99.29.59 99.89.59.39.99.29.59.89 99.89.59.39.99.29.59.89.89 99.89.59.39.99.29.59.89.89.29 99.89.59.39.99.29.59.89.89.29.9 99.89.59.39.99.29.59.89.89.29.9.79 99.89.59.39.99.29.59.89.89.29.9.79.49 99.89.59.39.99.29.59.89.89.29.9.79.49.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.7.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.1 0.1.1 0.1.1.2 0.1.1.2.2 0.1.1.2.2.2 0.1.1.2.2.2.3 0.1.1.2.2.2.3.3 0.1.1.2.2.2.3.3.4 0.1.1.2.2.2.3.3.4.5 0.1.1.2.2.2.3.3.4.5.5 0.1.1.2.2.2.3.3.4.5.5.6 0.1.1.2.2.2.3.3.4.5.5.6.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99} + +do_execsql_test 1.7.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.10 0.10.20 0.10.20.30 0.10.20.30.30 0.10.20.30.30.30 0.10.20.30.30.30.40 0.10.20.30.30.30.40.50 0.10.20.30.30.30.40.50.60 0.10.20.30.30.30.40.50.60.70 0.10.20.30.30.30.40.50.60.70.80 0.10.20.30.30.30.40.50.60.70.80.80 0.10.20.30.30.30.40.50.60.70.80.80.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 1 1.1 1.1.11 1.1.11.11 1.1.11.11.21 1.1.11.11.21.21 1.1.11.11.21.21.31 1.1.11.11.21.21.31.31 1.1.11.11.21.21.31.31.41 1.1.11.11.21.21.31.31.41.41 1.1.11.11.21.21.31.31.41.41.41 1.1.11.11.21.21.31.31.41.41.41.51 1.1.11.11.21.21.31.31.41.41.41.51.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 2 2.2 2.2.2 2.2.2.12 2.2.2.12.12 2.2.2.12.12.12 2.2.2.12.12.12.22 2.2.2.12.12.12.22.22 2.2.2.12.12.12.22.22.32 2.2.2.12.12.12.22.22.32.42 2.2.2.12.12.12.22.22.32.42.52 2.2.2.12.12.12.22.22.32.42.52.62 2.2.2.12.12.12.22.22.32.42.52.62.62 2.2.2.12.12.12.22.22.32.42.52.62.62.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 3 3.3 3.3.13 3.3.13.13 3.3.13.13.23 3.3.13.13.23.23 3.3.13.13.23.23.23 3.3.13.13.23.23.23.33 3.3.13.13.23.23.23.33.33 3.3.13.13.23.23.23.33.33.33 3.3.13.13.23.23.23.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 4 4.14 4.14.24 4.14.24.34 4.14.24.34.34 4.14.24.34.34.34 4.14.24.34.34.34.34 4.14.24.34.34.34.34.44 4.14.24.34.34.34.34.44.44 4.14.24.34.34.34.34.44.44.54 4.14.24.34.34.34.34.44.44.54.64 4.14.24.34.34.34.34.44.44.54.64.74 4.14.24.34.34.34.34.44.44.54.64.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 5 5.5 5.5.15 5.5.15.15 5.5.15.15.15 5.5.15.15.15.25 5.5.15.15.15.25.35 5.5.15.15.15.25.35.35 5.5.15.15.15.25.35.35.55 5.5.15.15.15.25.35.35.55.55 5.5.15.15.15.25.35.35.55.55.65 5.5.15.15.15.25.35.35.55.55.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 6 6.16 6.16.16 6.16.16.16 6.16.16.16.26 6.16.16.16.26.26 6.16.16.16.26.26.26 6.16.16.16.26.26.26.36 6.16.16.16.26.26.26.36.36 6.16.16.16.26.26.26.36.36.36 6.16.16.16.26.26.26.36.36.36.36 6.16.16.16.26.26.26.36.36.36.36.46 6.16.16.16.26.26.26.36.36.36.36.46.46 6.16.16.16.26.26.26.36.36.36.36.46.46.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 7 7.7 7.7.7 7.7.7.17 7.7.7.17.27 7.7.7.17.27.27 7.7.7.17.27.27.37 7.7.7.17.27.27.37.37 7.7.7.17.27.27.37.37.47 7.7.7.17.27.27.37.37.47.47 7.7.7.17.27.27.37.37.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47.57 7.7.7.17.27.27.37.37.47.47.47.47.57.67 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 8 8.8 8.8.8 8.8.8.28 8.8.8.28.38 8.8.8.28.38.38 8.8.8.28.38.38.58 8.8.8.28.38.38.58.58 8.8.8.28.38.38.58.58.58 8.8.8.28.38.38.58.58.58.58 8.8.8.28.38.38.58.58.58.58.68 8.8.8.28.38.38.58.58.58.58.68.78 8.8.8.28.38.38.58.58.58.58.68.78.78 8.8.8.28.38.38.58.58.58.58.68.78.78.88 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 9 9.9 9.9.9 9.9.9.19 9.9.9.19.29 9.9.9.19.29.29 9.9.9.19.29.29.29 9.9.9.19.29.29.29.39 9.9.9.19.29.29.29.39.39 9.9.9.19.29.29.29.39.39.39 9.9.9.19.29.29.29.39.39.39.49 9.9.9.19.29.29.29.39.39.39.49.59 9.9.9.19.29.29.29.39.39.39.49.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99} + +do_execsql_test 1.7.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 0.90.40.30.80.20.90.60.70.80.90.30 0.90.40.30.80.20.90.60.70.80.90.30.50 0.90.40.30.80.20.90.60.70.80.90.30.50.10 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.7.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.7.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {1 {} 2 74 3 74 4 74.74 5 74.74 6 74.74.99 7 74.74.99 8 74.74.99.33 9 74.74.99.33 10 74.74.99.33.89 11 74.74.99.33.89 12 74.74.99.33.89.96 13 74.74.99.33.89.96 14 74.74.99.33.89.96.38 15 74.74.99.33.89.96.38 16 74.74.99.33.89.96.38.39 17 74.74.99.33.89.96.38.39 18 74.74.99.33.89.96.38.39.91 19 74.74.99.33.89.96.38.39.91 20 74.74.99.33.89.96.38.39.91.6 21 74.74.99.33.89.96.38.39.91.6 22 74.74.99.33.89.96.38.39.91.6.97 23 74.74.99.33.89.96.38.39.91.6.97 24 74.74.99.33.89.96.38.39.91.6.97.46 25 74.74.99.33.89.96.38.39.91.6.97.46 26 74.74.99.33.89.96.38.39.91.6.97.46.54 27 74.74.99.33.89.96.38.39.91.6.97.46.54 28 74.74.99.33.89.96.38.39.91.6.97.46.54.8 29 74.74.99.33.89.96.38.39.91.6.97.46.54.8 30 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 31 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 32 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 33 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 34 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 35 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 36 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 37 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 38 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 39 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 40 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 41 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 42 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 43 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 44 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 45 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 46 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 47 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 48 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 49 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 50 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 51 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 52 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 53 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 54 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 55 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 56 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 57 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 58 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 59 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 60 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 61 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 62 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 63 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 64 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 65 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 66 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 67 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 68 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 69 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 70 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 71 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 72 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 73 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 74 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 75 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 76 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 77 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 78 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 79 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 80 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 81 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 82 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 83 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 84 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 85 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 86 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 87 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 88 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 89 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 90 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 91 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 92 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 93 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 94 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 95 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 96 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 97 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 98 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 99 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 100 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 101 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 102 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 103 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 104 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 105 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 106 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 107 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 108 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 109 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 110 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 111 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 112 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 113 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 114 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 115 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 116 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 117 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 118 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 119 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 120 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 121 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 122 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 123 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 124 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 125 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 126 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 127 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 128 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 129 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 130 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 131 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 132 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 133 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 134 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 135 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 136 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 137 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 138 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 139 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 140 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 141 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 142 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 143 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 144 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 145 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 146 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 147 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 148 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 149 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 150 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 151 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 152 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 153 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 154 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 155 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 156 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 157 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 158 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 159 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 160 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 161 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 162 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 163 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 164 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 165 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 166 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 167 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 168 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 169 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 170 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 171 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 172 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 173 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 174 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 175 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 176 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 177 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 178 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 179 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 180 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 181 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 182 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 183 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 184 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 185 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 186 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 187 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 188 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 189 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 190 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 191 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 192 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 193 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 194 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 195 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 196 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83 197 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83 198 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82 199 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82 200 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7} + +do_execsql_test 1.7.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {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 {}} + +do_execsql_test 1.7.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 21 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {}} + +do_execsql_test 1.7.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +} {1 89 2 89.6 3 89.6.29 4 89.6.29.47 5 89.6.29.47.59 6 89.6.29.47.59.28 7 89.6.29.47.59.28.75 8 89.6.29.47.59.28.75.78 9 89.6.29.47.59.28.75.78.72 10 89.6.29.47.59.28.75.78.72.98 11 89.6.29.47.59.28.75.78.72.98.87 12 89.6.29.47.59.28.75.78.72.98.87.73 13 89.6.29.47.59.28.75.78.72.98.87.73.96 14 89.6.29.47.59.28.75.78.72.98.87.73.96.74 15 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90 16 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75 17 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91 18 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69 19 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 21 {} 1 74 2 74.96 3 74.96.97 4 74.96.97.84 5 74.96.97.84.86 6 74.96.97.84.86.32 7 74.96.97.84.86.32.25 8 74.96.97.84.86.32.25.89 9 74.96.97.84.86.32.25.89.29 10 74.96.97.84.86.32.25.89.29.9 11 74.96.97.84.86.32.25.89.29.9.21 12 74.96.97.84.86.32.25.89.29.9.21.12 13 74.96.97.84.86.32.25.89.29.9.21.12.88 14 74.96.97.84.86.32.25.89.29.9.21.12.88.55 15 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70 16 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58 17 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81 18 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91 19 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 74 2 74.38 3 74.38.46 4 74.38.46.23 5 74.38.46.23.61 6 74.38.46.23.61.3 7 74.38.46.23.61.3.1 8 74.38.46.23.61.3.1.76 9 74.38.46.23.61.3.1.76.63 10 74.38.46.23.61.3.1.76.63.73 11 74.38.46.23.61.3.1.76.63.73.65 12 74.38.46.23.61.3.1.76.63.73.65.20 13 74.38.46.23.61.3.1.76.63.73.65.20.8 14 74.38.46.23.61.3.1.76.63.73.65.20.8.77 15 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19 16 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9 17 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23 18 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15 19 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 99 2 99.39 3 99.39.54 4 99.39.54.16 5 99.39.54.16.85 6 99.39.54.16.85.22 7 99.39.54.16.85.22.40 8 99.39.54.16.85.22.40.4 9 99.39.54.16.85.22.40.4.87 10 99.39.54.16.85.22.40.4.87.65 11 99.39.54.16.85.22.40.4.87.65.5 12 99.39.54.16.85.22.40.4.87.65.5.31 13 99.39.54.16.85.22.40.4.87.65.5.31.49 14 99.39.54.16.85.22.40.4.87.65.5.31.49.2 15 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26 16 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72 17 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13 18 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36 19 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 1 33 2 33.91 3 33.91.8 4 33.91.8.65 5 33.91.8.65.85 6 33.91.8.65.85.55 7 33.91.8.65.85.55.56 8 33.91.8.65.85.55.56.42 9 33.91.8.65.85.55.56.42.80 10 33.91.8.65.85.55.56.42.80.58 11 33.91.8.65.85.55.56.42.80.58.11 12 33.91.8.65.85.55.56.42.80.58.11.95 13 33.91.8.65.85.55.56.42.80.58.11.95.90 14 33.91.8.65.85.55.56.42.80.58.11.95.90.85 15 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47 16 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33 17 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14 18 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3 19 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {}} + +do_execsql_test 1.8.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 74 74 74 74 99 99 99 99 99 89 96 96 96 96 96 68 91 91 91 99 99 99 99 99 97 97 97 97 97 97 93 93 93 93 84 93 93 93 93 93 86 86 86 91 91 91 91 91 85 85 85 59 59 91 91 91 91 91 90 90 89 89 89 89 56 56 56 56 75 75 89 98 98 98 98 98 94 94 94 94 78 78 78 63 87 87 87 87 87 84 84 84 73 95 95 95 95 96 98 98 98 98 98 74 74 74 73 73 87 87 87 87 87 41 31 31 95 95 95 95 95 88 88 88 88 49 90 90 96 96 96 96 96 77 77 77 85 85 85 85 85 74 74 70 70 59 47 80 90 90 90 90 90 72 72 72 72 93 93 93 93 93 81 81 81 37 37 62 91 91 91 91 91 91 91 99 99 99 99 99 95 95 69 84 84 84 84 84 84 84 58 58 58 58 83 83 83 83 83 82} + +do_execsql_test 1.8.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 23 23 23 2 2 2 2 2 38 38 38 38 38 39 6 6 6 6 6 27 27 27 8 8 8 8 8 29 23 16 16 16 16 16 16 7 7 7 7 7 61 24 24 24 24 12 12 12 3 3 3 3 3 15 15 15 15 15 1 1 1 1 1 16 16 16 16 16 36 36 4 4 4 4 4 30 29 29 29 2 2 2 2 2 37 37 9 9 9 9 9 13 13 13 13 1 1 1 1 1 5 5 5 5 5 11 11 8 8 8 8 8 15 15 15 15 22 22 8 8 8 8 8 11 34 34 55 55 55 44 2 2 2 2 2 7 29 29 19 19 19 19 19 26 26 26 36 36 9 9 9 9 9 33 33 33 33 9 9 9 9 9 12 12 12 12 14 33 15 15 15 15 3 3 3 3 3 30 30 30 10 10 10 10 10 21 21 21 30 30 30 27 27 17 7 5} + +do_execsql_test 1.8.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.8.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.8.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.8.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.8.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.8.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.8.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.8.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.8.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.8.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.8.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.8.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.8.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.8.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.8.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.8.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.8.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.8.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.8.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 76 44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206} + +do_execsql_test 1.8.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.8.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 65 102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276} + +do_execsql_test 1.8.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 196 134 109 213 223 106 234 191 212 168 229 147 218 240 65 102 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 11 87 138 63 124 179 78 141 84 120 234 79 231 162 227 228 280 57 181 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 80 182 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 111 206 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 26 51 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 48 144 207 216 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 36 121 132 88 52 232 156 210 239 250 83 103 158 210 171 198 101 163 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276} + +do_execsql_test 1.8.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.8.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.8.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 56 {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} {} {} {} {} 4 {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 77 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 22 {} {} {} 12 {} {} {} {} {} {} {} {} {} {} {} {} 43 {} {} {} {} {} {} {} {} {} {} {} {} {} 33 {} {} {} {} {} {} {} {} 4 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 1 1 1 1 2 2 3 4 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} 91 {} {} {} {} {} 22 {} {} {} 12 {} {} {} {} {} {} {} {} {} {} {} {} 43 {} {} {} {} {} {} {} {} {} {} {} {} {} 33 {} {} {} {} {} {} {} {} 4 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 0 0 0 0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27} + +do_execsql_test 1.8.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 0 0 0 0 90 40 30 80 20 90 60 70 80 90 41 41 41 41 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 2 2 2 2 2 62 12 32 22 42 2 72 12 22 2 72 72 23 23 23 23 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 74 74 74 74 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 65 65 65 65 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 26 26 26 26 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 97 97 97 97 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 38 38 38 38 38 68 78 8 28 98 78 58 98 8 88 8 99 99 99 99 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.8.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98} + +do_execsql_test 1.8.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 10 20 30 30 30 40 50 60 70 80 1 1 1 1 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 2 2 2 2 2 2 2 12 12 12 22 22 32 42 52 62 62 3 3 3 3 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 4 4 4 4 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 5 5 5 5 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 6 6 6 6 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 7 7 7 7 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 8 8 8 8 8 8 8 28 38 38 58 58 58 58 68 78 9 9 9 9 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89} + +do_execsql_test 1.8.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 0 0 0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.8.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.8.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.8.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.8.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.8.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.8.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.8.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 0.74 0.74.41 0.74.41.74 0.74.41.74.23 74.41.74.23.99 41.74.23.99.26 74.23.99.26.33 23.99.26.33.2 99.26.33.2.89 26.33.2.89.81 33.2.89.81.96 2.89.81.96.59 89.81.96.59.38 81.96.59.38.68 96.59.38.68.39 59.38.68.39.62 38.68.39.62.91 68.39.62.91.46 39.62.91.46.6 62.91.46.6.99 91.46.6.99.97 46.6.99.97.27 6.99.97.27.46 99.97.27.46.78 97.27.46.78.54 27.46.78.54.97 46.78.54.97.8 78.54.97.8.67 54.97.8.67.29 97.8.67.29.93 8.67.29.93.84 67.29.93.84.77 29.93.84.77.23 93.84.77.23.16 84.77.23.16.16 77.23.16.16.93 23.16.16.93.65 16.16.93.65.35 16.93.65.35.47 93.65.35.47.7 65.35.47.7.86 35.47.7.86.74 47.7.86.74.61 7.86.74.61.91 86.74.61.91.85 74.61.91.85.24 61.91.85.24.85 91.85.24.85.43 85.24.85.43.59 24.85.43.59.12 85.43.59.12.32 43.59.12.32.56 59.12.32.56.3 12.32.56.3.91 32.56.3.91.22 56.3.91.22.90 3.91.22.90.55 91.22.90.55.15 22.90.55.15.28 90.55.15.28.89 55.15.28.89.25 15.28.89.25.47 28.89.25.47.1 89.25.47.1.56 25.47.1.56.40 47.1.56.40.43 1.56.40.43.56 56.40.43.56.16 40.43.56.16.75 43.56.16.75.36 56.16.75.36.89 16.75.36.89.98 75.36.89.98.76 36.89.98.76.81 89.98.76.81.4 98.76.81.4.94 76.81.4.94.42 81.4.94.42.30 4.94.42.30.78 94.42.30.78.33 42.30.78.33.29 30.78.33.29.53 78.33.29.53.63 33.29.53.63.2 29.53.63.2.87 53.63.2.87.37 63.2.87.37.80 2.87.37.80.84 87.37.80.84.72 37.80.84.72.41 80.84.72.41.9 84.72.41.9.61 72.41.9.61.73 41.9.61.73.95 9.61.73.95.65 61.73.95.65.13 73.95.65.13.58 95.65.13.58.96 65.13.58.96.98 13.58.96.98.1 58.96.98.1.21 96.98.1.21.74 98.1.21.74.65 1.21.74.65.35 21.74.65.35.5 74.65.35.5.73 65.35.5.73.11 35.5.73.11.51 5.73.11.51.87 73.11.51.87.41 11.51.87.41.12 51.87.41.12.8 87.41.12.8.20 41.12.8.20.31 12.8.20.31.31 8.20.31.31.15 20.31.31.15.95 31.31.15.95.22 31.15.95.22.73 15.95.22.73.79 95.22.73.79.88 22.73.79.88.34 73.79.88.34.8 79.88.34.8.11 88.34.8.11.49 34.8.11.49.34 8.11.49.34.90 11.49.34.90.59 49.34.90.59.96 34.90.59.96.60 90.59.96.60.55 59.96.60.55.75 96.60.55.75.77 60.55.75.77.44 55.75.77.44.2 75.77.44.2.7 77.44.2.7.85 44.2.7.85.57 2.7.85.57.74 7.85.57.74.29 85.57.74.29.70 57.74.29.70.59 74.29.70.59.19 29.70.59.19.39 70.59.19.39.26 59.19.39.26.26 19.39.26.26.47 39.26.26.47.80 26.26.47.80.90 26.47.80.90.36 47.80.90.36.58 80.90.36.58.47 90.36.58.47.9 36.58.47.9.72 58.47.9.72.72 47.9.72.72.66 9.72.72.66.33 72.72.66.33.93 72.66.33.93.75 66.33.93.75.64 33.93.75.64.81 93.75.64.81.9 75.64.81.9.23 64.81.9.23.37 81.9.23.37.13 9.23.37.13.12 23.37.13.12.14 37.13.12.14.62 13.12.14.62.91 12.14.62.91.36 14.62.91.36.91 62.91.36.91.33 91.36.91.33.15 36.91.33.15.34 91.33.15.34.36 33.15.34.36.99 15.34.36.99.3 34.36.99.3.95 36.99.3.95.69 99.3.95.69.58 3.95.69.58.52 95.69.58.52.30 69.58.52.30.50 58.52.30.50.84 52.30.50.84.10 30.50.84.10.84 50.84.10.84.33 84.10.84.33.21 10.84.33.21.39 84.33.21.39.44 33.21.39.44.58 21.39.44.58.30 39.44.58.30.38 44.58.30.38.34 58.30.38.34.83 30.38.34.83.27 38.34.83.27.82 34.83.27.82.17 83.27.82.17.7 27.82.17.7.5} + +do_execsql_test 1.8.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 90.40.30.80.20 40.30.80.20.90 30.80.20.90.60 80.20.90.60.70 20.90.60.70.80 90.60.70.80.90 60.70.80.90.30 70.80.90.30.50 80.90.30.50.10 90.30.50.10.30 41 41.81 41.81.91 41.81.91.61 41.81.91.61.91 81.91.61.91.91 91.61.91.91.1 61.91.91.1.81 91.91.1.81.41 91.1.81.41.61 1.81.41.61.1 81.41.61.1.21 41.61.1.21.11 61.1.21.11.51 1.21.11.51.41 21.11.51.41.31 11.51.41.31.31 51.41.31.31.11 41.31.31.11.81 31.31.11.81.91 31.11.81.91.91 11.81.91.91.21 2 2.62 2.62.12 2.62.12.32 2.62.12.32.22 62.12.32.22.42 12.32.22.42.2 32.22.42.2.72 22.42.2.72.12 42.2.72.12.22 2.72.12.22.2 72.12.22.2.72 12.22.2.72.72 22.2.72.72.12 2.72.72.12.62 72.72.12.62.52 72.12.62.52.82 23 23.33 23.33.93 23.33.93.23 23.33.93.23.93 33.93.23.93.43 93.23.93.43.3 23.93.43.3.43 93.43.3.43.33 43.3.43.33.53 3.43.33.53.63 43.33.53.63.73 33.53.63.73.13 53.63.73.13.73 63.73.13.73.73 73.13.73.73.33 13.73.73.33.93 73.73.33.93.23 73.33.93.23.13 33.93.23.13.33 93.23.13.33.3 23.13.33.3.33 13.33.3.33.83 74 74.74 74.74.54 74.74.54.84 74.74.54.84.74 74.54.84.74.24 54.84.74.24.4 84.74.24.4.94 74.24.4.94.84 24.4.94.84.74 4.94.84.74.34 94.84.74.34.34 84.74.34.34.44 74.34.34.44.74 34.34.44.74.64 34.44.74.64.14 44.74.64.14.34 74.64.14.34.84 64.14.34.84.84 14.34.84.84.44 34.84.84.44.34 65 65.35 65.35.85 65.35.85.85 65.35.85.85.55 35.85.85.55.15 85.85.55.15.25 85.55.15.25.75 55.15.25.75.95 15.25.75.95.65 25.75.95.65.65 75.95.65.65.35 95.65.65.35.5 65.65.35.5.15 65.35.5.15.95 35.5.15.95.55 5.15.95.55.75 15.95.55.75.85 95.55.75.85.75 55.75.85.75.15 75.85.75.15.95 85.75.15.95.5 26 26.96 26.96.46 26.96.46.6 26.96.46.6.46 96.46.6.46.16 46.6.46.16.16 6.46.16.16.86 46.16.16.86.56 16.16.86.56.56 16.86.56.56.56 86.56.56.56.16 56.56.56.16.36 56.56.16.36.76 56.16.36.76.96 16.36.76.96.96 36.76.96.96.26 76.96.96.26.26 96.96.26.26.36 96.26.26.36.66 26.26.36.66.36 26.36.66.36.36 97 97.27 97.27.97 97.27.97.67 97.27.97.67.77 27.97.67.77.47 97.67.77.47.7 67.77.47.7.47 77.47.7.47.87 47.7.47.87.37 7.47.87.37.87 47.87.37.87.77 87.37.87.77.7 37.87.77.7.57 87.77.7.57.47 77.7.57.47.47 7.57.47.47.37 57.47.47.37.27 47.47.37.27.17 47.37.27.17.7 38 38.68 38.68.78 38.68.78.8 38.68.78.8.28 68.78.8.28.98 78.8.28.98.78 8.28.98.78.58 28.98.78.58.98 98.78.58.98.8 78.58.98.8.88 58.98.8.88.8 98.8.88.8.58 8.88.8.58.58 88.8.58.58.58 8.58.58.58.38 99 99.89 99.89.59 99.89.59.39 99.89.59.39.99 89.59.39.99.29 59.39.99.29.59 39.99.29.59.89 99.29.59.89.89 29.59.89.89.29 59.89.89.29.9 89.89.29.9.79 89.29.9.79.49 29.9.79.49.59 9.79.49.59.29 79.49.59.29.59 49.59.29.59.19 59.29.59.19.39 29.59.19.39.9 59.19.39.9.9 19.39.9.9.99 39.9.9.99.69 9.9.99.69.39} + +do_execsql_test 1.8.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.1 0.1.1 0.1.1.2 0.1.1.2.2 1.1.2.2.2 1.2.2.2.3 2.2.2.3.3 2.2.3.3.4 2.3.3.4.5 3.3.4.5.5 3.4.5.5.6 4.5.5.6.7 5.5.6.7.7 5.6.7.7.7 6.7.7.7.8 7.7.7.8.8 7.7.8.8.8 7.8.8.8.9 8.8.8.9.9 8.8.9.9.9 8.9.9.9.10 9.9.9.10.11 9.9.10.11.11 9.10.11.11.12 10.11.11.12.12 11.11.12.12.12 11.12.12.12.13 12.12.12.13.13 12.12.13.13.14 12.13.13.14.15 13.13.14.15.15 13.14.15.15.15 14.15.15.15.16 15.15.15.16.16 15.15.16.16.16 15.16.16.16.17 16.16.16.17.19 16.16.17.19.20 16.17.19.20.21 17.19.20.21.21 19.20.21.21.22 20.21.21.22.22 21.21.22.22.23 21.22.22.23.23 22.22.23.23.23 22.23.23.23.24 23.23.23.24.25 23.23.24.25.26 23.24.25.26.26 24.25.26.26.26 25.26.26.26.27 26.26.26.27.27 26.26.27.27.28 26.27.27.28.29 27.27.28.29.29 27.28.29.29.29 28.29.29.29.30 29.29.29.30.30 29.29.30.30.30 29.30.30.30.31 30.30.30.31.31 30.30.31.31.32 30.31.31.32.33 31.31.32.33.33 31.32.33.33.33 32.33.33.33.33 33.33.33.33.33 33.33.33.33.34 33.33.33.34.34 33.33.34.34.34 33.34.34.34.34 34.34.34.34.35 34.34.34.35.35 34.34.35.35.36 34.35.35.36.36 35.35.36.36.36 35.36.36.36.36 36.36.36.36.37 36.36.36.37.37 36.36.37.37.38 36.37.37.38.38 37.37.38.38.39 37.38.38.39.39 38.38.39.39.39 38.39.39.39.40 39.39.39.40.41 39.39.40.41.41 39.40.41.41.41 40.41.41.41.42 41.41.41.42.43 41.41.42.43.43 41.42.43.43.44 42.43.43.44.44 43.43.44.44.46 43.44.44.46.46 44.44.46.46.47 44.46.46.47.47 46.46.47.47.47 46.47.47.47.47 47.47.47.47.49 47.47.47.49.50 47.47.49.50.51 47.49.50.51.52 49.50.51.52.53 50.51.52.53.54 51.52.53.54.55 52.53.54.55.55 53.54.55.55.56 54.55.55.56.56 55.55.56.56.56 55.56.56.56.57 56.56.56.57.58 56.56.57.58.58 56.57.58.58.58 57.58.58.58.58 58.58.58.58.59 58.58.58.59.59 58.58.59.59.59 58.59.59.59.59 59.59.59.59.60 59.59.59.60.61 59.59.60.61.61 59.60.61.61.62 60.61.61.62.62 61.61.62.62.63 61.62.62.63.64 62.62.63.64.65 62.63.64.65.65 63.64.65.65.65 64.65.65.65.66 65.65.65.66.67 65.65.66.67.68 65.66.67.68.69 66.67.68.69.70 67.68.69.70.72 68.69.70.72.72 69.70.72.72.72 70.72.72.72.73 72.72.72.73.73 72.72.73.73.73 72.73.73.73.74 73.73.73.74.74 73.73.74.74.74 73.74.74.74.74 74.74.74.74.74 74.74.74.74.75 74.74.74.75.75 74.74.75.75.75 74.75.75.75.76 75.75.75.76.77 75.75.76.77.77 75.76.77.77.78 76.77.77.78.78 77.77.78.78.79 77.78.78.79.80 78.78.79.80.80 78.79.80.80.81 79.80.80.81.81 80.80.81.81.81 80.81.81.81.82 81.81.81.82.83 81.81.82.83.84 81.82.83.84.84 82.83.84.84.84 83.84.84.84.84 84.84.84.84.85 84.84.84.85.85 84.84.85.85.85 84.85.85.85.86 85.85.85.86.87 85.85.86.87.87 85.86.87.87.88 86.87.87.88.89 87.87.88.89.89 87.88.89.89.89 88.89.89.89.90 89.89.89.90.90 89.89.90.90.90 89.90.90.90.91 90.90.90.91.91 90.90.91.91.91 90.91.91.91.91 91.91.91.91.91 91.91.91.91.93 91.91.91.93.93 91.91.93.93.93 91.93.93.93.94 93.93.93.94.95 93.93.94.95.95 93.94.95.95.95 94.95.95.95.96 95.95.95.96.96 95.95.96.96.96 95.96.96.96.97 96.96.96.97.97 96.96.97.97.98 96.97.97.98.98 97.97.98.98.99 97.98.98.99.99 98.98.99.99.99} + +do_execsql_test 1.8.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.10 0.10.20 0.10.20.30 0.10.20.30.30 10.20.30.30.30 20.30.30.30.40 30.30.30.40.50 30.30.40.50.60 30.40.50.60.70 40.50.60.70.80 50.60.70.80.80 60.70.80.80.90 70.80.80.90.90 80.80.90.90.90 1 1.1 1.1.11 1.1.11.11 1.1.11.11.21 1.11.11.21.21 11.11.21.21.31 11.21.21.31.31 21.21.31.31.41 21.31.31.41.41 31.31.41.41.41 31.41.41.41.51 41.41.41.51.61 41.41.51.61.61 41.51.61.61.81 51.61.61.81.81 61.61.81.81.81 61.81.81.81.91 81.81.81.91.91 81.81.91.91.91 81.91.91.91.91 91.91.91.91.91 2 2.2 2.2.2 2.2.2.12 2.2.2.12.12 2.2.12.12.12 2.12.12.12.22 12.12.12.22.22 12.12.22.22.32 12.22.22.32.42 22.22.32.42.52 22.32.42.52.62 32.42.52.62.62 42.52.62.62.72 52.62.62.72.72 62.62.72.72.72 62.72.72.72.82 3 3.3 3.3.13 3.3.13.13 3.3.13.13.23 3.13.13.23.23 13.13.23.23.23 13.23.23.23.33 23.23.23.33.33 23.23.33.33.33 23.33.33.33.33 33.33.33.33.33 33.33.33.33.43 33.33.33.43.43 33.33.43.43.53 33.43.43.53.63 43.43.53.63.73 43.53.63.73.73 53.63.73.73.73 63.73.73.73.83 73.73.73.83.93 73.73.83.93.93 73.83.93.93.93 4 4.14 4.14.24 4.14.24.34 4.14.24.34.34 14.24.34.34.34 24.34.34.34.34 34.34.34.34.44 34.34.34.44.44 34.34.44.44.54 34.44.44.54.64 44.44.54.64.74 44.54.64.74.74 54.64.74.74.74 64.74.74.74.74 74.74.74.74.74 74.74.74.74.84 74.74.74.84.84 74.74.84.84.84 74.84.84.84.84 84.84.84.84.94 5 5.5 5.5.15 5.5.15.15 5.5.15.15.15 5.15.15.15.25 15.15.15.25.35 15.15.25.35.35 15.25.35.35.55 25.35.35.55.55 35.35.55.55.65 35.55.55.65.65 55.55.65.65.65 55.65.65.65.75 65.65.65.75.75 65.65.75.75.75 65.75.75.75.85 75.75.75.85.85 75.75.85.85.85 75.85.85.85.95 85.85.85.95.95 85.85.95.95.95 6 6.16 6.16.16 6.16.16.16 6.16.16.16.26 16.16.16.26.26 16.16.26.26.26 16.26.26.26.36 26.26.26.36.36 26.26.36.36.36 26.36.36.36.36 36.36.36.36.46 36.36.36.46.46 36.36.46.46.56 36.46.46.56.56 46.46.56.56.56 46.56.56.56.66 56.56.56.66.76 56.56.66.76.86 56.66.76.86.96 66.76.86.96.96 76.86.96.96.96 7 7.7 7.7.7 7.7.7.17 7.7.7.17.27 7.7.17.27.27 7.17.27.27.37 17.27.27.37.37 27.27.37.37.47 27.37.37.47.47 37.37.47.47.47 37.47.47.47.47 47.47.47.47.57 47.47.47.57.67 47.47.57.67.77 47.57.67.77.77 57.67.77.77.87 67.77.77.87.87 77.77.87.87.97 77.87.87.97.97 8 8.8 8.8.8 8.8.8.28 8.8.8.28.38 8.8.28.38.38 8.28.38.38.58 28.38.38.58.58 38.38.58.58.58 38.58.58.58.58 58.58.58.58.68 58.58.58.68.78 58.58.68.78.78 58.68.78.78.88 68.78.78.88.98 78.78.88.98.98 9 9.9 9.9.9 9.9.9.19 9.9.9.19.29 9.9.19.29.29 9.19.29.29.29 19.29.29.29.39 29.29.29.39.39 29.29.39.39.39 29.39.39.39.49 39.39.39.49.59 39.39.49.59.59 39.49.59.59.59 49.59.59.59.59 59.59.59.59.69 59.59.59.69.79 59.59.69.79.89 59.69.79.89.89 69.79.89.89.89 79.89.89.89.99 89.89.89.99.99 89.89.99.99.99} + +do_execsql_test 1.8.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW ) FROM t2 +} {0 0.90 0.90.40 0.90.40.30 0.90.40.30.80 90.40.30.80.20 40.30.80.20.90 30.80.20.90.60 80.20.90.60.70 20.90.60.70.80 90.60.70.80.90 60.70.80.90.30 70.80.90.30.50 80.90.30.50.10 90.30.50.10.30 30.50.10.30.41 50.10.30.41.81 10.30.41.81.91 30.41.81.91.61 41.81.91.61.91 81.91.61.91.91 91.61.91.91.1 61.91.91.1.81 91.91.1.81.41 91.1.81.41.61 1.81.41.61.1 81.41.61.1.21 41.61.1.21.11 61.1.21.11.51 1.21.11.51.41 21.11.51.41.31 11.51.41.31.31 51.41.31.31.11 41.31.31.11.81 31.31.11.81.91 31.11.81.91.91 11.81.91.91.21 81.91.91.21.2 91.91.21.2.62 91.21.2.62.12 21.2.62.12.32 2.62.12.32.22 62.12.32.22.42 12.32.22.42.2 32.22.42.2.72 22.42.2.72.12 42.2.72.12.22 2.72.12.22.2 72.12.22.2.72 12.22.2.72.72 22.2.72.72.12 2.72.72.12.62 72.72.12.62.52 72.12.62.52.82 12.62.52.82.23 62.52.82.23.33 52.82.23.33.93 82.23.33.93.23 23.33.93.23.93 33.93.23.93.43 93.23.93.43.3 23.93.43.3.43 93.43.3.43.33 43.3.43.33.53 3.43.33.53.63 43.33.53.63.73 33.53.63.73.13 53.63.73.13.73 63.73.13.73.73 73.13.73.73.33 13.73.73.33.93 73.73.33.93.23 73.33.93.23.13 33.93.23.13.33 93.23.13.33.3 23.13.33.3.33 13.33.3.33.83 33.3.33.83.74 3.33.83.74.74 33.83.74.74.54 83.74.74.54.84 74.74.54.84.74 74.54.84.74.24 54.84.74.24.4 84.74.24.4.94 74.24.4.94.84 24.4.94.84.74 4.94.84.74.34 94.84.74.34.34 84.74.34.34.44 74.34.34.44.74 34.34.44.74.64 34.44.74.64.14 44.74.64.14.34 74.64.14.34.84 64.14.34.84.84 14.34.84.84.44 34.84.84.44.34 84.84.44.34.65 84.44.34.65.35 44.34.65.35.85 34.65.35.85.85 65.35.85.85.55 35.85.85.55.15 85.85.55.15.25 85.55.15.25.75 55.15.25.75.95 15.25.75.95.65 25.75.95.65.65 75.95.65.65.35 95.65.65.35.5 65.65.35.5.15 65.35.5.15.95 35.5.15.95.55 5.15.95.55.75 15.95.55.75.85 95.55.75.85.75 55.75.85.75.15 75.85.75.15.95 85.75.15.95.5 75.15.95.5.26 15.95.5.26.96 95.5.26.96.46 5.26.96.46.6 26.96.46.6.46 96.46.6.46.16 46.6.46.16.16 6.46.16.16.86 46.16.16.86.56 16.16.86.56.56 16.86.56.56.56 86.56.56.56.16 56.56.56.16.36 56.56.16.36.76 56.16.36.76.96 16.36.76.96.96 36.76.96.96.26 76.96.96.26.26 96.96.26.26.36 96.26.26.36.66 26.26.36.66.36 26.36.66.36.36 36.66.36.36.97 66.36.36.97.27 36.36.97.27.97 36.97.27.97.67 97.27.97.67.77 27.97.67.77.47 97.67.77.47.7 67.77.47.7.47 77.47.7.47.87 47.7.47.87.37 7.47.87.37.87 47.87.37.87.77 87.37.87.77.7 37.87.77.7.57 87.77.7.57.47 77.7.57.47.47 7.57.47.47.37 57.47.47.37.27 47.47.37.27.17 47.37.27.17.7 37.27.17.7.38 27.17.7.38.68 17.7.38.68.78 7.38.68.78.8 38.68.78.8.28 68.78.8.28.98 78.8.28.98.78 8.28.98.78.58 28.98.78.58.98 98.78.58.98.8 78.58.98.8.88 58.98.8.88.8 98.8.88.8.58 8.88.8.58.58 88.8.58.58.58 8.58.58.58.38 58.58.58.38.99 58.58.38.99.89 58.38.99.89.59 38.99.89.59.39 99.89.59.39.99 89.59.39.99.29 59.39.99.29.59 39.99.29.59.89 99.29.59.89.89 29.59.89.89.29 59.89.89.29.9 89.89.29.9.79 89.29.9.79.49 29.9.79.49.59 9.79.49.59.29 79.49.59.29.59 49.59.29.59.19 59.29.59.19.39 29.59.19.39.9 59.19.39.9.9 19.39.9.9.99 39.9.9.99.69 9.9.99.69.39} + +do_execsql_test 1.8.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.8.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) +} {1 {} 2 74 3 74 4 74.74 5 74.74 5 74.74.99 5 74.99 5 74.99.33 5 99.33 5 99.33.89 5 33.89 5 33.89.96 5 89.96 5 89.96.38 5 96.38 5 96.38.39 5 38.39 5 38.39.91 5 39.91 5 39.91.6 5 91.6 5 91.6.97 5 6.97 5 6.97.46 5 97.46 5 97.46.54 5 46.54 5 46.54.8 5 54.8 5 54.8.29 5 8.29 5 8.29.84 5 29.84 5 29.84.23 5 84.23 5 84.23.16 5 23.16 5 23.16.65 5 16.65 5 16.65.47 5 65.47 5 65.47.86 5 47.86 5 47.86.61 5 86.61 5 86.61.85 5 61.85 5 61.85.85 5 85.85 5 85.85.59 5 85.59 5 85.59.32 5 59.32 5 59.32.3 5 32.3 5 32.3.22 5 3.22 5 3.22.55 5 22.55 5 22.55.28 5 55.28 5 55.28.25 5 28.25 5 28.25.1 5 25.1 5 25.1.40 5 1.40 5 1.40.56 5 40.56 5 40.56.75 5 56.75 5 56.75.89 5 75.89 5 75.89.76 5 89.76 5 89.76.4 5 76.4 5 76.4.42 5 4.42 5 4.42.78 5 42.78 5 42.78.29 5 78.29 5 78.29.63 5 29.63 5 29.63.87 5 63.87 5 63.87.80 5 87.80 5 87.80.72 5 80.72 5 80.72.9 5 72.9 5 72.9.73 5 9.73 5 9.73.65 5 73.65 5 73.65.58 5 65.58 5 65.58.98 5 58.98 5 58.98.21 5 98.21 5 98.21.65 5 21.65 5 21.65.5 5 65.5 5 65.5.11 5 5.11 5 5.11.87 5 11.87 5 11.87.12 5 87.12 5 87.12.20 5 12.20 5 12.20.31 5 20.31 5 20.31.95 5 31.95 5 31.95.73 5 95.73 5 95.73.88 5 73.88 5 73.88.8 5 88.8 5 88.8.49 5 8.49 5 8.49.90 5 49.90 5 49.90.96 5 90.96 5 90.96.55 5 96.55 5 96.55.77 5 55.77 5 55.77.2 5 77.2 5 77.2.85 5 2.85 5 2.85.74 5 85.74 5 85.74.70 5 74.70 5 74.70.19 5 70.19 5 70.19.26 5 19.26 5 19.26.47 5 26.47 5 26.47.90 5 47.90 5 47.90.58 5 90.58 5 90.58.9 5 58.9 5 58.9.72 5 9.72 5 9.72.33 5 72.33 5 72.33.75 5 33.75 5 33.75.81 5 75.81 5 75.81.23 5 81.23 5 81.23.13 5 23.13 5 23.13.14 5 13.14 5 13.14.91 5 14.91 5 14.91.91 5 91.91 5 91.91.15 5 91.15 5 91.15.36 5 15.36 5 15.36.3 5 36.3 5 36.3.69 5 3.69 5 3.69.52 5 69.52 5 69.52.50 5 52.50 5 52.50.10 5 50.10 5 50.10.33 5 10.33 5 10.33.39 5 33.39 5 33.39.58 5 39.58 5 39.58.38 5 58.38 5 58.38.83 5 38.83 5 38.83.82 5 83.82 5 83.82.7 5 82.7} + +do_execsql_test 1.8.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) +} {1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {}} + +do_execsql_test 1.8.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) +} {1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {}} + +do_execsql_test 1.8.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) +} {1 89 2 89.6 3 89.6.29 4 89.6.29.47 5 89.6.29.47.59 5 6.29.47.59.28 5 29.47.59.28.75 5 47.59.28.75.78 5 59.28.75.78.72 5 28.75.78.72.98 5 75.78.72.98.87 5 78.72.98.87.73 5 72.98.87.73.96 5 98.87.73.96.74 5 87.73.96.74.90 5 73.96.74.90.75 5 96.74.90.75.91 5 74.90.75.91.69 5 90.75.91.69.39 5 75.91.69.39.7 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 74 2 74.96 3 74.96.97 4 74.96.97.84 5 74.96.97.84.86 5 96.97.84.86.32 5 97.84.86.32.25 5 84.86.32.25.89 5 86.32.25.89.29 5 32.25.89.29.9 5 25.89.29.9.21 5 89.29.9.21.12 5 29.9.21.12.88 5 9.21.12.88.55 5 21.12.88.55.70 5 12.88.55.70.58 5 88.55.70.58.81 5 55.70.58.81.91 5 70.58.81.91.52 5 58.81.91.52.58 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 74 2 74.38 3 74.38.46 4 74.38.46.23 5 74.38.46.23.61 5 38.46.23.61.3 5 46.23.61.3.1 5 23.61.3.1.76 5 61.3.1.76.63 5 3.1.76.63.73 5 1.76.63.73.65 5 76.63.73.65.20 5 63.73.65.20.8 5 73.65.20.8.77 5 65.20.8.77.19 5 20.8.77.19.9 5 8.77.19.9.23 5 77.19.9.23.15 5 19.9.23.15.50 5 9.23.15.50.38 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 99 2 99.39 3 99.39.54 4 99.39.54.16 5 99.39.54.16.85 5 39.54.16.85.22 5 54.16.85.22.40 5 16.85.22.40.4 5 85.22.40.4.87 5 22.40.4.87.65 5 40.4.87.65.5 5 4.87.65.5.31 5 87.65.5.31.49 5 65.5.31.49.2 5 5.31.49.2.26 5 31.49.2.26.72 5 49.2.26.72.13 5 2.26.72.13.36 5 26.72.13.36.10 5 72.13.36.10.83 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 1 33 2 33.91 3 33.91.8 4 33.91.8.65 5 33.91.8.65.85 5 91.8.65.85.55 5 8.65.85.55.56 5 65.85.55.56.42 5 85.55.56.42.80 5 55.56.42.80.58 5 56.42.80.58.11 5 42.80.58.11.95 5 80.58.11.95.90 5 58.11.95.90.85 5 11.95.90.85.47 5 95.90.85.47.33 5 90.85.47.33.14 5 85.47.33.14.3 5 47.33.14.3.33 5 33.14.3.33.82 1 {} 2 {} 3 {} 4 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {}} + +do_execsql_test 1.9.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.9.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.9.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.9.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.9.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.9.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.9.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.9.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.9.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.9.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.9.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.9.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {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} + +do_execsql_test 1.9.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.9.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.9.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.9.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.9.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.9.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.9.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.9.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.9.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 76 44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206} + +do_execsql_test 1.9.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.9.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 65 102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276} + +do_execsql_test 1.9.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 196 134 109 213 223 106 234 191 212 168 229 147 218 240 65 102 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 11 87 138 63 124 179 78 141 84 120 234 79 231 162 227 228 280 57 181 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 80 182 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 111 206 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 26 51 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 48 144 207 216 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 36 121 132 88 52 232 156 210 239 250 83 103 158 210 171 198 101 163 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276} + +do_execsql_test 1.9.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {1 147 106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229} + +do_execsql_test 1.9.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.9.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.9.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.9.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99} + +do_execsql_test 1.9.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 10 20 30 30 30 40 50 60 70 80 80 90 90 90 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 2 2 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 8 8 8 28 38 38 58 58 58 58 68 78 78 88 98 98 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99} + +do_execsql_test 1.9.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.9.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.9.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.9.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.9.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.9.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.9.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.9.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.9.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.9.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99} + +do_execsql_test 1.9.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 10 20 30 30 30 40 50 60 70 80 80 90 90 90 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 2 2 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 8 8 8 28 38 38 58 58 58 58 68 78 78 88 98 98 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99} + +do_execsql_test 1.9.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.9.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.9.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 {} 1 74 1 {} 1 74 1 {} 1 99 1 {} 1 33 1 {} 1 89 1 {} 1 96 1 {} 1 38 1 {} 1 39 1 {} 1 91 1 {} 1 6 1 {} 1 97 1 {} 1 46 1 {} 1 54 1 {} 1 8 1 {} 1 29 1 {} 1 84 1 {} 1 23 1 {} 1 16 1 {} 1 65 1 {} 1 47 1 {} 1 86 1 {} 1 61 1 {} 1 85 1 {} 1 85 1 {} 1 59 1 {} 1 32 1 {} 1 3 1 {} 1 22 1 {} 1 55 1 {} 1 28 1 {} 1 25 1 {} 1 1 1 {} 1 40 1 {} 1 56 1 {} 1 75 1 {} 1 89 1 {} 1 76 1 {} 1 4 1 {} 1 42 1 {} 1 78 1 {} 1 29 1 {} 1 63 1 {} 1 87 1 {} 1 80 1 {} 1 72 1 {} 1 9 1 {} 1 73 1 {} 1 65 1 {} 1 58 1 {} 1 98 1 {} 1 21 1 {} 1 65 1 {} 1 5 1 {} 1 11 1 {} 1 87 1 {} 1 12 1 {} 1 20 1 {} 1 31 1 {} 1 95 1 {} 1 73 1 {} 1 88 1 {} 1 8 1 {} 1 49 1 {} 1 90 1 {} 1 96 1 {} 1 55 1 {} 1 77 1 {} 1 2 1 {} 1 85 1 {} 1 74 1 {} 1 70 1 {} 1 19 1 {} 1 26 1 {} 1 47 1 {} 1 90 1 {} 1 58 1 {} 1 9 1 {} 1 72 1 {} 1 33 1 {} 1 75 1 {} 1 81 1 {} 1 23 1 {} 1 13 1 {} 1 14 1 {} 1 91 1 {} 1 91 1 {} 1 15 1 {} 1 36 1 {} 1 3 1 {} 1 69 1 {} 1 52 1 {} 1 50 1 {} 1 10 1 {} 1 33 1 {} 1 39 1 {} 1 58 1 {} 1 38 1 {} 1 83 1 {} 1 82 1 {} 1 7 1 {}} + +do_execsql_test 1.9.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {}} + +do_execsql_test 1.9.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {}} + +do_execsql_test 1.9.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW) +} {1 89 1 6 1 29 1 47 1 59 1 28 1 75 1 78 1 72 1 98 1 87 1 73 1 96 1 74 1 90 1 75 1 91 1 69 1 39 1 7 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 74 1 96 1 97 1 84 1 86 1 32 1 25 1 89 1 29 1 9 1 21 1 12 1 88 1 55 1 70 1 58 1 81 1 91 1 52 1 58 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 74 1 38 1 46 1 23 1 61 1 3 1 1 1 76 1 63 1 73 1 65 1 20 1 8 1 77 1 19 1 9 1 23 1 15 1 50 1 38 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 99 1 39 1 54 1 16 1 85 1 22 1 40 1 4 1 87 1 65 1 5 1 31 1 49 1 2 1 26 1 72 1 13 1 36 1 10 1 83 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 33 1 91 1 8 1 65 1 85 1 55 1 56 1 42 1 80 1 58 1 11 1 95 1 90 1 85 1 47 1 33 1 14 1 3 1 33 1 82 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {} 1 {}} + +do_execsql_test 1.10.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {74 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.10.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.10.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.10.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.10.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.10.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.10.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.10.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.10.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.10.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.10.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.10.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.10.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.10.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.10.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.10.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.10.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.10.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.10.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.10.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.10.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206 206 206 206 206} + +do_execsql_test 1.10.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {168 134 218 191 212 229 240 213 234 196 223 223 223 223 223 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 210 210 210 210 78 120 87 162 124 141 138 227 228 179 231 234 280 280 280 280 280 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 279 279 279 279 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 229 229 229 229 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 206 206 206 206 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 212 212 212 212 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 207 207 207 207 88 171 158 156 198 121 210 132 210 239 250 232 232 232 232 232 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229 229 229} + +do_execsql_test 1.10.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276 276 276 276 276} + +do_execsql_test 1.10.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {213 223 106 234 191 212 168 229 147 218 240 240 240 240 240 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 263 263 263 263 124 179 78 141 84 120 234 79 231 162 227 228 280 280 280 280 280 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 252 252 252 252 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 171 171 171 171 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 274 274 274 274 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 226 226 226 226 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 124 124 124 124 52 232 156 210 239 250 83 103 158 210 171 198 198 198 198 198 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276 276 276 276 276} + +do_execsql_test 1.10.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229 229 229} + +do_execsql_test 1.10.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.10.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 41 {} {} {} {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} 2 {} 29 {} {} {} 46 62 62 {} {} 16 {} 33 {} {} {} {} {} 78 {} 61 {} 59 77 90 74 {} 27 {} 22 39 67 {} 54 85 74 90 7 61 90 62 {} 93 {} {} 94 {} 23 {} 74 93 30 23 29 3 1 41 80 65 33 2 98 86 89 25 76 65 40 38 15 13 96 74 97 81 40 16 99 76 96 32 80 86 59 2 99 84 84 39 65 27 76 78 84 16 2 96 59 16 41 28 13 89 22 4 42 91 41 33 87 55 81 29 36 28 6 47 97 97 85 33 41 93 15 85 89 98 98 43 23 73 4 56 29 89 46 65 38 59 68 47 9 93 9 23 39 16 93 98 74 65 75 15 56 93 12 2 81 2 23 97 47 91 15 93 35 16 63 8 53 91 33 99} + +do_execsql_test 1.10.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 81 {} {} {} 81 {} 21 {} {} {} {} 21 {} {} {} 21 12 {} {} {} {} {} 12 {} 72 {} 12 {} {} 72 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} 73 {} {} {} {} {} 73 {} 23 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 15 55 {} {} {} {} {} 55 {} 15 {} {} {} 16 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 47 {} {} {} {} {} 27 47 {} {} {} {} {} {} {} {} {} 98 {} 98 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 29 {} {} {} {} {} 9 {} 29 29 {} {} {}} + +do_execsql_test 1.10.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 8 9 9 10 10 11 11 11 11 11 12 12 12 12 12 13 13 13 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 25 25 25 25 26 26 27 27 28 29 29 29 29 29 29 30 30 30 30 30 30 30 30 30 31 31 31 32 32 33 33 33 33 33 33 33 34 34 34 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 36 37 37 37 38 38 38 38 38 39 39 39 39 39 39 40 40 40 41 41 41 41 42 42 42 43 43 43 43 43 43 43 43 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 47 47} + +do_execsql_test 1.10.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 2 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 13 13 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 90 {} {} {} 90 1 30 {} {} 31 31 30 {} {} {} 1 40 {} 50 11 81 42 40 {} 50 81 40 {} {} 50 {} 52 {} 41 81 {} 41 {} 2 30 2 81 82 53 {} 10 {} {} 81 {} 41 10 81 30 81 {} 3 3 23 94 3 61 80 {} 94 3 91 91 72 3 63 30 91 94 94 72 91 73 91 84 84 33 41 1 33 84 73 73 91 20 41 84 33 33 84 33 41 84 20 21 44 22 90 22 81 81 74 93 93 93 81 21 83 44 44 21 21 21 13 21 21 34 11 34 73 74 2 60 2 34 2 34 74 60 23 2 2 2 11 91 60 62 73 74 70 51 65 74 93 65 70 34 70 93 93 93 62 35 44 43 12 35 41 43 44 44 41 80 54 72 43 41 43 91 12 80 80 35 33 12} + +do_execsql_test 1.10.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.10.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.10.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.10.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9} + +do_execsql_test 1.10.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.10.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.10.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.10.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.10.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.10.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.10.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.10.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0.74.41.74.23 0.74.41.74.23.99 0.74.41.74.23.99.26 0.74.41.74.23.99.26.33 0.74.41.74.23.99.26.33.2 0.74.41.74.23.99.26.33.2.89 0.74.41.74.23.99.26.33.2.89.81 0.74.41.74.23.99.26.33.2.89.81.96 0.74.41.74.23.99.26.33.2.89.81.96.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5} + +do_execsql_test 1.10.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 0.90.40.30.80.20.90.60.70.80.90.30 0.90.40.30.80.20.90.60.70.80.90.30.50 0.90.40.30.80.20.90.60.70.80.90.30.50.10 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 41.81.91.61.91 41.81.91.61.91.91 41.81.91.61.91.91.1 41.81.91.61.91.91.1.81 41.81.91.61.91.91.1.81.41 41.81.91.61.91.91.1.81.41.61 41.81.91.61.91.91.1.81.41.61.1 41.81.91.61.91.91.1.81.41.61.1.21 41.81.91.61.91.91.1.81.41.61.1.21.11 41.81.91.61.91.91.1.81.41.61.1.21.11.51 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 2.62.12.32.22 2.62.12.32.22.42 2.62.12.32.22.42.2 2.62.12.32.22.42.2.72 2.62.12.32.22.42.2.72.12 2.62.12.32.22.42.2.72.12.22 2.62.12.32.22.42.2.72.12.22.2 2.62.12.32.22.42.2.72.12.22.2.72 2.62.12.32.22.42.2.72.12.22.2.72.72 2.62.12.32.22.42.2.72.12.22.2.72.72.12 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 23.33.93.23.93 23.33.93.23.93.43 23.33.93.23.93.43.3 23.33.93.23.93.43.3.43 23.33.93.23.93.43.3.43.33 23.33.93.23.93.43.3.43.33.53 23.33.93.23.93.43.3.43.33.53.63 23.33.93.23.93.43.3.43.33.53.63.73 23.33.93.23.93.43.3.43.33.53.63.73.13 23.33.93.23.93.43.3.43.33.53.63.73.13.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 74.74.54.84.74 74.74.54.84.74.24 74.74.54.84.74.24.4 74.74.54.84.74.24.4.94 74.74.54.84.74.24.4.94.84 74.74.54.84.74.24.4.94.84.74 74.74.54.84.74.24.4.94.84.74.34 74.74.54.84.74.24.4.94.84.74.34.34 74.74.54.84.74.24.4.94.84.74.34.34.44 74.74.54.84.74.24.4.94.84.74.34.34.44.74 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 65.35.85.85.55 65.35.85.85.55.15 65.35.85.85.55.15.25 65.35.85.85.55.15.25.75 65.35.85.85.55.15.25.75.95 65.35.85.85.55.15.25.75.95.65 65.35.85.85.55.15.25.75.95.65.65 65.35.85.85.55.15.25.75.95.65.65.35 65.35.85.85.55.15.25.75.95.65.65.35.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 26.96.46.6.46 26.96.46.6.46.16 26.96.46.6.46.16.16 26.96.46.6.46.16.16.86 26.96.46.6.46.16.16.86.56 26.96.46.6.46.16.16.86.56.56 26.96.46.6.46.16.16.86.56.56.56 26.96.46.6.46.16.16.86.56.56.56.16 26.96.46.6.46.16.16.86.56.56.56.16.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 97.27.97.67.77 97.27.97.67.77.47 97.27.97.67.77.47.7 97.27.97.67.77.47.7.47 97.27.97.67.77.47.7.47.87 97.27.97.67.77.47.7.47.87.37 97.27.97.67.77.47.7.47.87.37.87 97.27.97.67.77.47.7.47.87.37.87.77 97.27.97.67.77.47.7.47.87.37.87.77.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 38.68.78.8.28 38.68.78.8.28.98 38.68.78.8.28.98.78 38.68.78.8.28.98.78.58 38.68.78.8.28.98.78.58.98 38.68.78.8.28.98.78.58.98.8 38.68.78.8.28.98.78.58.98.8.88 38.68.78.8.28.98.78.58.98.8.88.8 38.68.78.8.28.98.78.58.98.8.88.8.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 99.89.59.39.99 99.89.59.39.99.29 99.89.59.39.99.29.59 99.89.59.39.99.29.59.89 99.89.59.39.99.29.59.89.89 99.89.59.39.99.29.59.89.89.29 99.89.59.39.99.29.59.89.89.29.9 99.89.59.39.99.29.59.89.89.29.9.79 99.89.59.39.99.29.59.89.89.29.9.79.49 99.89.59.39.99.29.59.89.89.29.9.79.49.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.10.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0.1.1.2.2 0.1.1.2.2.2 0.1.1.2.2.2.3 0.1.1.2.2.2.3.3 0.1.1.2.2.2.3.3.4 0.1.1.2.2.2.3.3.4.5 0.1.1.2.2.2.3.3.4.5.5 0.1.1.2.2.2.3.3.4.5.5.6 0.1.1.2.2.2.3.3.4.5.5.6.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99} + +do_execsql_test 1.10.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0.10.20.30.30 0.10.20.30.30.30 0.10.20.30.30.30.40 0.10.20.30.30.30.40.50 0.10.20.30.30.30.40.50.60 0.10.20.30.30.30.40.50.60.70 0.10.20.30.30.30.40.50.60.70.80 0.10.20.30.30.30.40.50.60.70.80.80 0.10.20.30.30.30.40.50.60.70.80.80.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 1.1.11.11.21 1.1.11.11.21.21 1.1.11.11.21.21.31 1.1.11.11.21.21.31.31 1.1.11.11.21.21.31.31.41 1.1.11.11.21.21.31.31.41.41 1.1.11.11.21.21.31.31.41.41.41 1.1.11.11.21.21.31.31.41.41.41.51 1.1.11.11.21.21.31.31.41.41.41.51.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 2.2.2.12.12 2.2.2.12.12.12 2.2.2.12.12.12.22 2.2.2.12.12.12.22.22 2.2.2.12.12.12.22.22.32 2.2.2.12.12.12.22.22.32.42 2.2.2.12.12.12.22.22.32.42.52 2.2.2.12.12.12.22.22.32.42.52.62 2.2.2.12.12.12.22.22.32.42.52.62.62 2.2.2.12.12.12.22.22.32.42.52.62.62.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 3.3.13.13.23 3.3.13.13.23.23 3.3.13.13.23.23.23 3.3.13.13.23.23.23.33 3.3.13.13.23.23.23.33.33 3.3.13.13.23.23.23.33.33.33 3.3.13.13.23.23.23.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33 3.3.13.13.23.23.23.33.33.33.33.33.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 4.14.24.34.34 4.14.24.34.34.34 4.14.24.34.34.34.34 4.14.24.34.34.34.34.44 4.14.24.34.34.34.34.44.44 4.14.24.34.34.34.34.44.44.54 4.14.24.34.34.34.34.44.44.54.64 4.14.24.34.34.34.34.44.44.54.64.74 4.14.24.34.34.34.34.44.44.54.64.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 5.5.15.15.15 5.5.15.15.15.25 5.5.15.15.15.25.35 5.5.15.15.15.25.35.35 5.5.15.15.15.25.35.35.55 5.5.15.15.15.25.35.35.55.55 5.5.15.15.15.25.35.35.55.55.65 5.5.15.15.15.25.35.35.55.55.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65 5.5.15.15.15.25.35.35.55.55.65.65.65.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 6.16.16.16.26 6.16.16.16.26.26 6.16.16.16.26.26.26 6.16.16.16.26.26.26.36 6.16.16.16.26.26.26.36.36 6.16.16.16.26.26.26.36.36.36 6.16.16.16.26.26.26.36.36.36.36 6.16.16.16.26.26.26.36.36.36.36.46 6.16.16.16.26.26.26.36.36.36.36.46.46 6.16.16.16.26.26.26.36.36.36.36.46.46.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 7.7.7.17.27 7.7.7.17.27.27 7.7.7.17.27.27.37 7.7.7.17.27.27.37.37 7.7.7.17.27.27.37.37.47 7.7.7.17.27.27.37.37.47.47 7.7.7.17.27.27.37.37.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47 7.7.7.17.27.27.37.37.47.47.47.47.57 7.7.7.17.27.27.37.37.47.47.47.47.57.67 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 8.8.8.28.38 8.8.8.28.38.38 8.8.8.28.38.38.58 8.8.8.28.38.38.58.58 8.8.8.28.38.38.58.58.58 8.8.8.28.38.38.58.58.58.58 8.8.8.28.38.38.58.58.58.58.68 8.8.8.28.38.38.58.58.58.58.68.78 8.8.8.28.38.38.58.58.58.58.68.78.78 8.8.8.28.38.38.58.58.58.58.68.78.78.88 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 9.9.9.19.29 9.9.9.19.29.29 9.9.9.19.29.29.29 9.9.9.19.29.29.29.39 9.9.9.19.29.29.29.39.39 9.9.9.19.29.29.29.39.39.39 9.9.9.19.29.29.29.39.39.39.49 9.9.9.19.29.29.29.39.39.39.49.59 9.9.9.19.29.29.29.39.39.39.49.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99} + +do_execsql_test 1.10.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING ) FROM t2 +} {0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 0.90.40.30.80.20.90.60 0.90.40.30.80.20.90.60.70 0.90.40.30.80.20.90.60.70.80 0.90.40.30.80.20.90.60.70.80.90 0.90.40.30.80.20.90.60.70.80.90.30 0.90.40.30.80.20.90.60.70.80.90.30.50 0.90.40.30.80.20.90.60.70.80.90.30.50.10 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.10.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.10.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) +} {5 74.74 6 74.74.99 7 74.74.99 8 74.74.99.33 9 74.74.99.33 10 74.74.99.33.89 11 74.74.99.33.89 12 74.74.99.33.89.96 13 74.74.99.33.89.96 14 74.74.99.33.89.96.38 15 74.74.99.33.89.96.38 16 74.74.99.33.89.96.38.39 17 74.74.99.33.89.96.38.39 18 74.74.99.33.89.96.38.39.91 19 74.74.99.33.89.96.38.39.91 20 74.74.99.33.89.96.38.39.91.6 21 74.74.99.33.89.96.38.39.91.6 22 74.74.99.33.89.96.38.39.91.6.97 23 74.74.99.33.89.96.38.39.91.6.97 24 74.74.99.33.89.96.38.39.91.6.97.46 25 74.74.99.33.89.96.38.39.91.6.97.46 26 74.74.99.33.89.96.38.39.91.6.97.46.54 27 74.74.99.33.89.96.38.39.91.6.97.46.54 28 74.74.99.33.89.96.38.39.91.6.97.46.54.8 29 74.74.99.33.89.96.38.39.91.6.97.46.54.8 30 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 31 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29 32 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 33 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84 34 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 35 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23 36 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 37 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16 38 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 39 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65 40 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 41 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47 42 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 43 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86 44 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 45 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61 46 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 47 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85 48 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 49 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85 50 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 51 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59 52 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 53 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32 54 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 55 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3 56 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 57 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22 58 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 59 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55 60 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 61 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28 62 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 63 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25 64 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 65 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1 66 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 67 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40 68 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 69 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56 70 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 71 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75 72 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 73 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89 74 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 75 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76 76 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 77 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4 78 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 79 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42 80 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 81 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78 82 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 83 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29 84 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 85 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63 86 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 87 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87 88 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 89 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80 90 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 91 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72 92 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 93 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9 94 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 95 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73 96 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 97 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65 98 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 99 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58 100 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 101 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98 102 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 103 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21 104 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 105 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65 106 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 107 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5 108 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 109 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11 110 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 111 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87 112 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 113 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12 114 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 115 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20 116 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 117 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31 118 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 119 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95 120 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 121 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73 122 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 123 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88 124 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 125 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8 126 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 127 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49 128 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 129 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90 130 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 131 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96 132 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 133 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55 134 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 135 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77 136 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 137 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2 138 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 139 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85 140 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 141 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74 142 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 143 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70 144 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 145 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19 146 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 147 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26 148 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 149 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47 150 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 151 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90 152 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 153 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58 154 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 155 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9 156 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 157 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72 158 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 159 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33 160 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 161 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75 162 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 163 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81 164 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 165 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23 166 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 167 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13 168 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 169 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14 170 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 171 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91 172 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 173 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91 174 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 175 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15 176 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 177 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36 178 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 179 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3 180 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 181 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69 182 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 183 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52 184 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 185 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50 186 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 187 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10 188 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 189 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33 190 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 191 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39 192 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 193 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58 194 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 195 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38 196 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83 197 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83 198 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82 199 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82 200 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7} + +do_execsql_test 1.10.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) +} {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 {} 201 {} 201 {} 201 {} 201 {}} + +do_execsql_test 1.10.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) +} {5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 21 {} 21 {} 21 {} 21 {} 21 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {}} + +do_execsql_test 1.10.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING) +} {5 89.6.29.47.59 6 89.6.29.47.59.28 7 89.6.29.47.59.28.75 8 89.6.29.47.59.28.75.78 9 89.6.29.47.59.28.75.78.72 10 89.6.29.47.59.28.75.78.72.98 11 89.6.29.47.59.28.75.78.72.98.87 12 89.6.29.47.59.28.75.78.72.98.87.73 13 89.6.29.47.59.28.75.78.72.98.87.73.96 14 89.6.29.47.59.28.75.78.72.98.87.73.96.74 15 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90 16 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75 17 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91 18 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69 19 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 21 {} 21 {} 21 {} 21 {} 21 {} 5 74.96.97.84.86 6 74.96.97.84.86.32 7 74.96.97.84.86.32.25 8 74.96.97.84.86.32.25.89 9 74.96.97.84.86.32.25.89.29 10 74.96.97.84.86.32.25.89.29.9 11 74.96.97.84.86.32.25.89.29.9.21 12 74.96.97.84.86.32.25.89.29.9.21.12 13 74.96.97.84.86.32.25.89.29.9.21.12.88 14 74.96.97.84.86.32.25.89.29.9.21.12.88.55 15 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70 16 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58 17 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81 18 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91 19 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 74.38.46.23.61 6 74.38.46.23.61.3 7 74.38.46.23.61.3.1 8 74.38.46.23.61.3.1.76 9 74.38.46.23.61.3.1.76.63 10 74.38.46.23.61.3.1.76.63.73 11 74.38.46.23.61.3.1.76.63.73.65 12 74.38.46.23.61.3.1.76.63.73.65.20 13 74.38.46.23.61.3.1.76.63.73.65.20.8 14 74.38.46.23.61.3.1.76.63.73.65.20.8.77 15 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19 16 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9 17 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23 18 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15 19 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 99.39.54.16.85 6 99.39.54.16.85.22 7 99.39.54.16.85.22.40 8 99.39.54.16.85.22.40.4 9 99.39.54.16.85.22.40.4.87 10 99.39.54.16.85.22.40.4.87.65 11 99.39.54.16.85.22.40.4.87.65.5 12 99.39.54.16.85.22.40.4.87.65.5.31 13 99.39.54.16.85.22.40.4.87.65.5.31.49 14 99.39.54.16.85.22.40.4.87.65.5.31.49.2 15 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26 16 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72 17 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13 18 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36 19 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {} 5 33.91.8.65.85 6 33.91.8.65.85.55 7 33.91.8.65.85.55.56 8 33.91.8.65.85.55.56.42 9 33.91.8.65.85.55.56.42.80 10 33.91.8.65.85.55.56.42.80.58 11 33.91.8.65.85.55.56.42.80.58.11 12 33.91.8.65.85.55.56.42.80.58.11.95 13 33.91.8.65.85.55.56.42.80.58.11.95.90 14 33.91.8.65.85.55.56.42.80.58.11.95.90.85 15 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47 16 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33 17 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14 18 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3 19 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 5 {} 6 {} 7 {} 8 {} 9 {} 10 {} 11 {} 12 {} 13 {} 14 {} 15 {} 16 {} 17 {} 18 {} 19 {} 20 {} 20 {} 20 {} 20 {} 20 {}} + +do_execsql_test 1.11.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {74 74 74 99 99 99 99 99 99 99 96 96 96 96 96 96 91 91 99 99 99 99 99 99 99 97 97 97 97 97 97 93 93 93 93 93 93 93 93 93 93 86 91 91 91 91 91 91 91 85 85 85 91 91 91 91 91 91 91 90 90 89 89 89 89 56 56 75 75 89 98 98 98 98 98 98 98 94 94 94 94 78 78 87 87 87 87 87 87 87 84 84 95 95 95 95 96 98 98 98 98 98 98 98 74 74 74 87 87 87 87 87 87 87 41 95 95 95 95 95 95 95 88 88 88 90 90 96 96 96 96 96 96 96 77 85 85 85 85 85 85 85 74 74 70 70 80 90 90 90 90 90 90 90 72 72 93 93 93 93 93 93 93 81 81 81 62 91 91 91 91 91 91 91 99 99 99 99 99 99 99 95 95 84 84 84 84 84 84 84 84 58 58 83 83 83 83 83 83 83 82} + +do_execsql_test 1.11.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 0 0 0 0 23 2 2 2 2 2 2 2 38 38 38 38 6 6 6 6 6 6 6 27 8 8 8 8 8 8 8 16 16 16 16 16 16 7 7 7 7 7 7 7 24 24 24 12 12 12 3 3 3 3 3 3 3 15 15 15 1 1 1 1 1 1 1 16 16 16 16 16 4 4 4 4 4 4 4 29 29 2 2 2 2 2 2 2 9 9 9 9 9 9 9 13 13 1 1 1 1 1 1 1 5 5 5 5 5 8 8 8 8 8 8 8 15 15 15 15 8 8 8 8 8 8 8 11 34 34 55 44 2 2 2 2 2 2 2 7 19 19 19 19 19 19 19 26 26 26 9 9 9 9 9 9 9 33 33 9 9 9 9 9 9 9 12 12 12 12 14 15 15 15 3 3 3 3 3 3 3 30 10 10 10 10 10 10 10 21 21 21 30 27 27 17 7 5 5 5} + +do_execsql_test 1.11.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.11.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.11.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.11.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.11.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.11.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.11.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.11.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.11.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.11.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.11.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.11.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.11.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.11.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.11.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.11.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.11.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.11.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.11.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {44 78 28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206 206 206} + +do_execsql_test 1.11.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {106 109 168 134 218 191 212 229 240 213 234 196 223 223 223 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 210 210 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 280 280 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 279 279 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 229 229 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 206 206 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 212 212 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 207 207 103 36 88 171 158 156 198 121 210 132 210 239 250 232 232 232 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229} + +do_execsql_test 1.11.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {102 11 87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276 276 276} + +do_execsql_test 1.11.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {134 109 213 223 106 234 191 212 168 229 147 218 240 240 240 119 136 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 263 263 138 63 124 179 78 141 84 120 234 79 231 162 227 228 280 280 280 110 179 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 252 252 71 157 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 171 171 74 132 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 274 274 52 85 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 226 226 207 216 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 124 124 132 88 52 232 156 210 239 250 83 103 158 210 171 198 198 198 172 163 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276 276 276} + +do_execsql_test 1.11.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {106 109 168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229} + +do_execsql_test 1.11.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.11.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 97 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 56 {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} {} {} {} {} 4 {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 {} {} {} {} 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 77 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} 12 {} {} {} {} {} 22 {} {} {} 12 {} {} {} {} {} {} {} {} {} {} {} {} 43 {} {} {} {} {} {} {} {} {} {} {} {} {} 33 {} {} {} {} {} {} {} {} 4 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 15 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 1 1 1 1 2 2 3 4 5 6 7 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 2 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 13 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} 91 {} {} {} {} {} 22 {} {} {} 12 {} {} {} {} {} {} {} {} {} {} {} {} 43 {} {} {} {} {} {} {} {} {} {} {} {} {} 33 {} {} {} {} {} {} {} {} 4 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 15 {} {} {} {} {} {} {} {} 26 {} {} {} 16 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 0 0 0 0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27} + +do_execsql_test 1.11.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 0 0 0 0 90 40 30 80 20 90 60 70 80 90 41 41 41 41 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 2 2 2 2 2 62 12 32 22 42 2 72 12 22 2 72 72 23 23 23 23 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 74 74 74 74 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 65 65 65 65 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 26 26 26 26 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 97 97 97 97 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 38 38 38 38 38 68 78 8 28 98 78 58 98 8 88 8 99 99 99 99 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.11.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 0 0 0 0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98} + +do_execsql_test 1.11.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 0 0 0 0 10 20 30 30 30 40 50 60 70 80 1 1 1 1 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 2 2 2 2 2 2 2 12 12 12 22 22 32 42 52 62 62 3 3 3 3 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 4 4 4 4 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 5 5 5 5 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 6 6 6 6 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 7 7 7 7 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 8 8 8 8 8 8 8 28 38 38 58 58 58 58 68 78 9 9 9 9 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89} + +do_execsql_test 1.11.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 0 0 0 0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.11.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.11.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.11.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.11.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.11.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.11.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.11.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0.74.41 0.74.41.74 0.74.41.74.23 0.74.41.74.23.99 0.74.41.74.23.99.26 74.41.74.23.99.26.33 41.74.23.99.26.33.2 74.23.99.26.33.2.89 23.99.26.33.2.89.81 99.26.33.2.89.81.96 26.33.2.89.81.96.59 33.2.89.81.96.59.38 2.89.81.96.59.38.68 89.81.96.59.38.68.39 81.96.59.38.68.39.62 96.59.38.68.39.62.91 59.38.68.39.62.91.46 38.68.39.62.91.46.6 68.39.62.91.46.6.99 39.62.91.46.6.99.97 62.91.46.6.99.97.27 91.46.6.99.97.27.46 46.6.99.97.27.46.78 6.99.97.27.46.78.54 99.97.27.46.78.54.97 97.27.46.78.54.97.8 27.46.78.54.97.8.67 46.78.54.97.8.67.29 78.54.97.8.67.29.93 54.97.8.67.29.93.84 97.8.67.29.93.84.77 8.67.29.93.84.77.23 67.29.93.84.77.23.16 29.93.84.77.23.16.16 93.84.77.23.16.16.93 84.77.23.16.16.93.65 77.23.16.16.93.65.35 23.16.16.93.65.35.47 16.16.93.65.35.47.7 16.93.65.35.47.7.86 93.65.35.47.7.86.74 65.35.47.7.86.74.61 35.47.7.86.74.61.91 47.7.86.74.61.91.85 7.86.74.61.91.85.24 86.74.61.91.85.24.85 74.61.91.85.24.85.43 61.91.85.24.85.43.59 91.85.24.85.43.59.12 85.24.85.43.59.12.32 24.85.43.59.12.32.56 85.43.59.12.32.56.3 43.59.12.32.56.3.91 59.12.32.56.3.91.22 12.32.56.3.91.22.90 32.56.3.91.22.90.55 56.3.91.22.90.55.15 3.91.22.90.55.15.28 91.22.90.55.15.28.89 22.90.55.15.28.89.25 90.55.15.28.89.25.47 55.15.28.89.25.47.1 15.28.89.25.47.1.56 28.89.25.47.1.56.40 89.25.47.1.56.40.43 25.47.1.56.40.43.56 47.1.56.40.43.56.16 1.56.40.43.56.16.75 56.40.43.56.16.75.36 40.43.56.16.75.36.89 43.56.16.75.36.89.98 56.16.75.36.89.98.76 16.75.36.89.98.76.81 75.36.89.98.76.81.4 36.89.98.76.81.4.94 89.98.76.81.4.94.42 98.76.81.4.94.42.30 76.81.4.94.42.30.78 81.4.94.42.30.78.33 4.94.42.30.78.33.29 94.42.30.78.33.29.53 42.30.78.33.29.53.63 30.78.33.29.53.63.2 78.33.29.53.63.2.87 33.29.53.63.2.87.37 29.53.63.2.87.37.80 53.63.2.87.37.80.84 63.2.87.37.80.84.72 2.87.37.80.84.72.41 87.37.80.84.72.41.9 37.80.84.72.41.9.61 80.84.72.41.9.61.73 84.72.41.9.61.73.95 72.41.9.61.73.95.65 41.9.61.73.95.65.13 9.61.73.95.65.13.58 61.73.95.65.13.58.96 73.95.65.13.58.96.98 95.65.13.58.96.98.1 65.13.58.96.98.1.21 13.58.96.98.1.21.74 58.96.98.1.21.74.65 96.98.1.21.74.65.35 98.1.21.74.65.35.5 1.21.74.65.35.5.73 21.74.65.35.5.73.11 74.65.35.5.73.11.51 65.35.5.73.11.51.87 35.5.73.11.51.87.41 5.73.11.51.87.41.12 73.11.51.87.41.12.8 11.51.87.41.12.8.20 51.87.41.12.8.20.31 87.41.12.8.20.31.31 41.12.8.20.31.31.15 12.8.20.31.31.15.95 8.20.31.31.15.95.22 20.31.31.15.95.22.73 31.31.15.95.22.73.79 31.15.95.22.73.79.88 15.95.22.73.79.88.34 95.22.73.79.88.34.8 22.73.79.88.34.8.11 73.79.88.34.8.11.49 79.88.34.8.11.49.34 88.34.8.11.49.34.90 34.8.11.49.34.90.59 8.11.49.34.90.59.96 11.49.34.90.59.96.60 49.34.90.59.96.60.55 34.90.59.96.60.55.75 90.59.96.60.55.75.77 59.96.60.55.75.77.44 96.60.55.75.77.44.2 60.55.75.77.44.2.7 55.75.77.44.2.7.85 75.77.44.2.7.85.57 77.44.2.7.85.57.74 44.2.7.85.57.74.29 2.7.85.57.74.29.70 7.85.57.74.29.70.59 85.57.74.29.70.59.19 57.74.29.70.59.19.39 74.29.70.59.19.39.26 29.70.59.19.39.26.26 70.59.19.39.26.26.47 59.19.39.26.26.47.80 19.39.26.26.47.80.90 39.26.26.47.80.90.36 26.26.47.80.90.36.58 26.47.80.90.36.58.47 47.80.90.36.58.47.9 80.90.36.58.47.9.72 90.36.58.47.9.72.72 36.58.47.9.72.72.66 58.47.9.72.72.66.33 47.9.72.72.66.33.93 9.72.72.66.33.93.75 72.72.66.33.93.75.64 72.66.33.93.75.64.81 66.33.93.75.64.81.9 33.93.75.64.81.9.23 93.75.64.81.9.23.37 75.64.81.9.23.37.13 64.81.9.23.37.13.12 81.9.23.37.13.12.14 9.23.37.13.12.14.62 23.37.13.12.14.62.91 37.13.12.14.62.91.36 13.12.14.62.91.36.91 12.14.62.91.36.91.33 14.62.91.36.91.33.15 62.91.36.91.33.15.34 91.36.91.33.15.34.36 36.91.33.15.34.36.99 91.33.15.34.36.99.3 33.15.34.36.99.3.95 15.34.36.99.3.95.69 34.36.99.3.95.69.58 36.99.3.95.69.58.52 99.3.95.69.58.52.30 3.95.69.58.52.30.50 95.69.58.52.30.50.84 69.58.52.30.50.84.10 58.52.30.50.84.10.84 52.30.50.84.10.84.33 30.50.84.10.84.33.21 50.84.10.84.33.21.39 84.10.84.33.21.39.44 10.84.33.21.39.44.58 84.33.21.39.44.58.30 33.21.39.44.58.30.38 21.39.44.58.30.38.34 39.44.58.30.38.34.83 44.58.30.38.34.83.27 58.30.38.34.83.27.82 30.38.34.83.27.82.17 38.34.83.27.82.17.7 34.83.27.82.17.7.5 83.27.82.17.7.5 27.82.17.7.5} + +do_execsql_test 1.11.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 90.40.30.80.20.90.60 40.30.80.20.90.60.70 30.80.20.90.60.70.80 80.20.90.60.70.80.90 20.90.60.70.80.90.30 90.60.70.80.90.30.50 60.70.80.90.30.50.10 70.80.90.30.50.10.30 80.90.30.50.10.30 90.30.50.10.30 41.81.91 41.81.91.61 41.81.91.61.91 41.81.91.61.91.91 41.81.91.61.91.91.1 81.91.61.91.91.1.81 91.61.91.91.1.81.41 61.91.91.1.81.41.61 91.91.1.81.41.61.1 91.1.81.41.61.1.21 1.81.41.61.1.21.11 81.41.61.1.21.11.51 41.61.1.21.11.51.41 61.1.21.11.51.41.31 1.21.11.51.41.31.31 21.11.51.41.31.31.11 11.51.41.31.31.11.81 51.41.31.31.11.81.91 41.31.31.11.81.91.91 31.31.11.81.91.91.21 31.11.81.91.91.21 11.81.91.91.21 2.62.12 2.62.12.32 2.62.12.32.22 2.62.12.32.22.42 2.62.12.32.22.42.2 62.12.32.22.42.2.72 12.32.22.42.2.72.12 32.22.42.2.72.12.22 22.42.2.72.12.22.2 42.2.72.12.22.2.72 2.72.12.22.2.72.72 72.12.22.2.72.72.12 12.22.2.72.72.12.62 22.2.72.72.12.62.52 2.72.72.12.62.52.82 72.72.12.62.52.82 72.12.62.52.82 23.33.93 23.33.93.23 23.33.93.23.93 23.33.93.23.93.43 23.33.93.23.93.43.3 33.93.23.93.43.3.43 93.23.93.43.3.43.33 23.93.43.3.43.33.53 93.43.3.43.33.53.63 43.3.43.33.53.63.73 3.43.33.53.63.73.13 43.33.53.63.73.13.73 33.53.63.73.13.73.73 53.63.73.13.73.73.33 63.73.13.73.73.33.93 73.13.73.73.33.93.23 13.73.73.33.93.23.13 73.73.33.93.23.13.33 73.33.93.23.13.33.3 33.93.23.13.33.3.33 93.23.13.33.3.33.83 23.13.33.3.33.83 13.33.3.33.83 74.74.54 74.74.54.84 74.74.54.84.74 74.74.54.84.74.24 74.74.54.84.74.24.4 74.54.84.74.24.4.94 54.84.74.24.4.94.84 84.74.24.4.94.84.74 74.24.4.94.84.74.34 24.4.94.84.74.34.34 4.94.84.74.34.34.44 94.84.74.34.34.44.74 84.74.34.34.44.74.64 74.34.34.44.74.64.14 34.34.44.74.64.14.34 34.44.74.64.14.34.84 44.74.64.14.34.84.84 74.64.14.34.84.84.44 64.14.34.84.84.44.34 14.34.84.84.44.34 34.84.84.44.34 65.35.85 65.35.85.85 65.35.85.85.55 65.35.85.85.55.15 65.35.85.85.55.15.25 35.85.85.55.15.25.75 85.85.55.15.25.75.95 85.55.15.25.75.95.65 55.15.25.75.95.65.65 15.25.75.95.65.65.35 25.75.95.65.65.35.5 75.95.65.65.35.5.15 95.65.65.35.5.15.95 65.65.35.5.15.95.55 65.35.5.15.95.55.75 35.5.15.95.55.75.85 5.15.95.55.75.85.75 15.95.55.75.85.75.15 95.55.75.85.75.15.95 55.75.85.75.15.95.5 75.85.75.15.95.5 85.75.15.95.5 26.96.46 26.96.46.6 26.96.46.6.46 26.96.46.6.46.16 26.96.46.6.46.16.16 96.46.6.46.16.16.86 46.6.46.16.16.86.56 6.46.16.16.86.56.56 46.16.16.86.56.56.56 16.16.86.56.56.56.16 16.86.56.56.56.16.36 86.56.56.56.16.36.76 56.56.56.16.36.76.96 56.56.16.36.76.96.96 56.16.36.76.96.96.26 16.36.76.96.96.26.26 36.76.96.96.26.26.36 76.96.96.26.26.36.66 96.96.26.26.36.66.36 96.26.26.36.66.36.36 26.26.36.66.36.36 26.36.66.36.36 97.27.97 97.27.97.67 97.27.97.67.77 97.27.97.67.77.47 97.27.97.67.77.47.7 27.97.67.77.47.7.47 97.67.77.47.7.47.87 67.77.47.7.47.87.37 77.47.7.47.87.37.87 47.7.47.87.37.87.77 7.47.87.37.87.77.7 47.87.37.87.77.7.57 87.37.87.77.7.57.47 37.87.77.7.57.47.47 87.77.7.57.47.47.37 77.7.57.47.47.37.27 7.57.47.47.37.27.17 57.47.47.37.27.17.7 47.47.37.27.17.7 47.37.27.17.7 38.68.78 38.68.78.8 38.68.78.8.28 38.68.78.8.28.98 38.68.78.8.28.98.78 68.78.8.28.98.78.58 78.8.28.98.78.58.98 8.28.98.78.58.98.8 28.98.78.58.98.8.88 98.78.58.98.8.88.8 78.58.98.8.88.8.58 58.98.8.88.8.58.58 98.8.88.8.58.58.58 8.88.8.58.58.58.38 88.8.58.58.58.38 8.58.58.58.38 99.89.59 99.89.59.39 99.89.59.39.99 99.89.59.39.99.29 99.89.59.39.99.29.59 89.59.39.99.29.59.89 59.39.99.29.59.89.89 39.99.29.59.89.89.29 99.29.59.89.89.29.9 29.59.89.89.29.9.79 59.89.89.29.9.79.49 89.89.29.9.79.49.59 89.29.9.79.49.59.29 29.9.79.49.59.29.59 9.79.49.59.29.59.19 79.49.59.29.59.19.39 49.59.29.59.19.39.9 59.29.59.19.39.9.9 29.59.19.39.9.9.99 59.19.39.9.9.99.69 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39} + +do_execsql_test 1.11.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0.1.1 0.1.1.2 0.1.1.2.2 0.1.1.2.2.2 0.1.1.2.2.2.3 1.1.2.2.2.3.3 1.2.2.2.3.3.4 2.2.2.3.3.4.5 2.2.3.3.4.5.5 2.3.3.4.5.5.6 3.3.4.5.5.6.7 3.4.5.5.6.7.7 4.5.5.6.7.7.7 5.5.6.7.7.7.8 5.6.7.7.7.8.8 6.7.7.7.8.8.8 7.7.7.8.8.8.9 7.7.8.8.8.9.9 7.8.8.8.9.9.9 8.8.8.9.9.9.10 8.8.9.9.9.10.11 8.9.9.9.10.11.11 9.9.9.10.11.11.12 9.9.10.11.11.12.12 9.10.11.11.12.12.12 10.11.11.12.12.12.13 11.11.12.12.12.13.13 11.12.12.12.13.13.14 12.12.12.13.13.14.15 12.12.13.13.14.15.15 12.13.13.14.15.15.15 13.13.14.15.15.15.16 13.14.15.15.15.16.16 14.15.15.15.16.16.16 15.15.15.16.16.16.17 15.15.16.16.16.17.19 15.16.16.16.17.19.20 16.16.16.17.19.20.21 16.16.17.19.20.21.21 16.17.19.20.21.21.22 17.19.20.21.21.22.22 19.20.21.21.22.22.23 20.21.21.22.22.23.23 21.21.22.22.23.23.23 21.22.22.23.23.23.24 22.22.23.23.23.24.25 22.23.23.23.24.25.26 23.23.23.24.25.26.26 23.23.24.25.26.26.26 23.24.25.26.26.26.27 24.25.26.26.26.27.27 25.26.26.26.27.27.28 26.26.26.27.27.28.29 26.26.27.27.28.29.29 26.27.27.28.29.29.29 27.27.28.29.29.29.30 27.28.29.29.29.30.30 28.29.29.29.30.30.30 29.29.29.30.30.30.31 29.29.30.30.30.31.31 29.30.30.30.31.31.32 30.30.30.31.31.32.33 30.30.31.31.32.33.33 30.31.31.32.33.33.33 31.31.32.33.33.33.33 31.32.33.33.33.33.33 32.33.33.33.33.33.34 33.33.33.33.33.34.34 33.33.33.33.34.34.34 33.33.33.34.34.34.34 33.33.34.34.34.34.35 33.34.34.34.34.35.35 34.34.34.34.35.35.36 34.34.34.35.35.36.36 34.34.35.35.36.36.36 34.35.35.36.36.36.36 35.35.36.36.36.36.37 35.36.36.36.36.37.37 36.36.36.36.37.37.38 36.36.36.37.37.38.38 36.36.37.37.38.38.39 36.37.37.38.38.39.39 37.37.38.38.39.39.39 37.38.38.39.39.39.40 38.38.39.39.39.40.41 38.39.39.39.40.41.41 39.39.39.40.41.41.41 39.39.40.41.41.41.42 39.40.41.41.41.42.43 40.41.41.41.42.43.43 41.41.41.42.43.43.44 41.41.42.43.43.44.44 41.42.43.43.44.44.46 42.43.43.44.44.46.46 43.43.44.44.46.46.47 43.44.44.46.46.47.47 44.44.46.46.47.47.47 44.46.46.47.47.47.47 46.46.47.47.47.47.49 46.47.47.47.47.49.50 47.47.47.47.49.50.51 47.47.47.49.50.51.52 47.47.49.50.51.52.53 47.49.50.51.52.53.54 49.50.51.52.53.54.55 50.51.52.53.54.55.55 51.52.53.54.55.55.56 52.53.54.55.55.56.56 53.54.55.55.56.56.56 54.55.55.56.56.56.57 55.55.56.56.56.57.58 55.56.56.56.57.58.58 56.56.56.57.58.58.58 56.56.57.58.58.58.58 56.57.58.58.58.58.59 57.58.58.58.58.59.59 58.58.58.58.59.59.59 58.58.58.59.59.59.59 58.58.59.59.59.59.60 58.59.59.59.59.60.61 59.59.59.59.60.61.61 59.59.59.60.61.61.62 59.59.60.61.61.62.62 59.60.61.61.62.62.63 60.61.61.62.62.63.64 61.61.62.62.63.64.65 61.62.62.63.64.65.65 62.62.63.64.65.65.65 62.63.64.65.65.65.66 63.64.65.65.65.66.67 64.65.65.65.66.67.68 65.65.65.66.67.68.69 65.65.66.67.68.69.70 65.66.67.68.69.70.72 66.67.68.69.70.72.72 67.68.69.70.72.72.72 68.69.70.72.72.72.73 69.70.72.72.72.73.73 70.72.72.72.73.73.73 72.72.72.73.73.73.74 72.72.73.73.73.74.74 72.73.73.73.74.74.74 73.73.73.74.74.74.74 73.73.74.74.74.74.74 73.74.74.74.74.74.75 74.74.74.74.74.75.75 74.74.74.74.75.75.75 74.74.74.75.75.75.76 74.74.75.75.75.76.77 74.75.75.75.76.77.77 75.75.75.76.77.77.78 75.75.76.77.77.78.78 75.76.77.77.78.78.79 76.77.77.78.78.79.80 77.77.78.78.79.80.80 77.78.78.79.80.80.81 78.78.79.80.80.81.81 78.79.80.80.81.81.81 79.80.80.81.81.81.82 80.80.81.81.81.82.83 80.81.81.81.82.83.84 81.81.81.82.83.84.84 81.81.82.83.84.84.84 81.82.83.84.84.84.84 82.83.84.84.84.84.85 83.84.84.84.84.85.85 84.84.84.84.85.85.85 84.84.84.85.85.85.86 84.84.85.85.85.86.87 84.85.85.85.86.87.87 85.85.85.86.87.87.88 85.85.86.87.87.88.89 85.86.87.87.88.89.89 86.87.87.88.89.89.89 87.87.88.89.89.89.90 87.88.89.89.89.90.90 88.89.89.89.90.90.90 89.89.89.90.90.90.91 89.89.90.90.90.91.91 89.90.90.90.91.91.91 90.90.90.91.91.91.91 90.90.91.91.91.91.91 90.91.91.91.91.91.93 91.91.91.91.91.93.93 91.91.91.91.93.93.93 91.91.91.93.93.93.94 91.91.93.93.93.94.95 91.93.93.93.94.95.95 93.93.93.94.95.95.95 93.93.94.95.95.95.96 93.94.95.95.95.96.96 94.95.95.95.96.96.96 95.95.95.96.96.96.97 95.95.96.96.96.97.97 95.96.96.96.97.97.98 96.96.96.97.97.98.98 96.96.97.97.98.98.99 96.97.97.98.98.99.99 97.97.98.98.99.99.99 97.98.98.99.99.99 98.98.99.99.99} + +do_execsql_test 1.11.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0.10.20 0.10.20.30 0.10.20.30.30 0.10.20.30.30.30 0.10.20.30.30.30.40 10.20.30.30.30.40.50 20.30.30.30.40.50.60 30.30.30.40.50.60.70 30.30.40.50.60.70.80 30.40.50.60.70.80.80 40.50.60.70.80.80.90 50.60.70.80.80.90.90 60.70.80.80.90.90.90 70.80.80.90.90.90 80.80.90.90.90 1.1.11 1.1.11.11 1.1.11.11.21 1.1.11.11.21.21 1.1.11.11.21.21.31 1.11.11.21.21.31.31 11.11.21.21.31.31.41 11.21.21.31.31.41.41 21.21.31.31.41.41.41 21.31.31.41.41.41.51 31.31.41.41.41.51.61 31.41.41.41.51.61.61 41.41.41.51.61.61.81 41.41.51.61.61.81.81 41.51.61.61.81.81.81 51.61.61.81.81.81.91 61.61.81.81.81.91.91 61.81.81.81.91.91.91 81.81.81.91.91.91.91 81.81.91.91.91.91.91 81.91.91.91.91.91 91.91.91.91.91 2.2.2 2.2.2.12 2.2.2.12.12 2.2.2.12.12.12 2.2.2.12.12.12.22 2.2.12.12.12.22.22 2.12.12.12.22.22.32 12.12.12.22.22.32.42 12.12.22.22.32.42.52 12.22.22.32.42.52.62 22.22.32.42.52.62.62 22.32.42.52.62.62.72 32.42.52.62.62.72.72 42.52.62.62.72.72.72 52.62.62.72.72.72.82 62.62.72.72.72.82 62.72.72.72.82 3.3.13 3.3.13.13 3.3.13.13.23 3.3.13.13.23.23 3.3.13.13.23.23.23 3.13.13.23.23.23.33 13.13.23.23.23.33.33 13.23.23.23.33.33.33 23.23.23.33.33.33.33 23.23.33.33.33.33.33 23.33.33.33.33.33.43 33.33.33.33.33.43.43 33.33.33.33.43.43.53 33.33.33.43.43.53.63 33.33.43.43.53.63.73 33.43.43.53.63.73.73 43.43.53.63.73.73.73 43.53.63.73.73.73.83 53.63.73.73.73.83.93 63.73.73.73.83.93.93 73.73.73.83.93.93.93 73.73.83.93.93.93 73.83.93.93.93 4.14.24 4.14.24.34 4.14.24.34.34 4.14.24.34.34.34 4.14.24.34.34.34.34 14.24.34.34.34.34.44 24.34.34.34.34.44.44 34.34.34.34.44.44.54 34.34.34.44.44.54.64 34.34.44.44.54.64.74 34.44.44.54.64.74.74 44.44.54.64.74.74.74 44.54.64.74.74.74.74 54.64.74.74.74.74.74 64.74.74.74.74.74.84 74.74.74.74.74.84.84 74.74.74.74.84.84.84 74.74.74.84.84.84.84 74.74.84.84.84.84.94 74.84.84.84.84.94 84.84.84.84.94 5.5.15 5.5.15.15 5.5.15.15.15 5.5.15.15.15.25 5.5.15.15.15.25.35 5.15.15.15.25.35.35 15.15.15.25.35.35.55 15.15.25.35.35.55.55 15.25.35.35.55.55.65 25.35.35.55.55.65.65 35.35.55.55.65.65.65 35.55.55.65.65.65.75 55.55.65.65.65.75.75 55.65.65.65.75.75.75 65.65.65.75.75.75.85 65.65.75.75.75.85.85 65.75.75.75.85.85.85 75.75.75.85.85.85.95 75.75.85.85.85.95.95 75.85.85.85.95.95.95 85.85.85.95.95.95 85.85.95.95.95 6.16.16 6.16.16.16 6.16.16.16.26 6.16.16.16.26.26 6.16.16.16.26.26.26 16.16.16.26.26.26.36 16.16.26.26.26.36.36 16.26.26.26.36.36.36 26.26.26.36.36.36.36 26.26.36.36.36.36.46 26.36.36.36.36.46.46 36.36.36.36.46.46.56 36.36.36.46.46.56.56 36.36.46.46.56.56.56 36.46.46.56.56.56.66 46.46.56.56.56.66.76 46.56.56.56.66.76.86 56.56.56.66.76.86.96 56.56.66.76.86.96.96 56.66.76.86.96.96.96 66.76.86.96.96.96 76.86.96.96.96 7.7.7 7.7.7.17 7.7.7.17.27 7.7.7.17.27.27 7.7.7.17.27.27.37 7.7.17.27.27.37.37 7.17.27.27.37.37.47 17.27.27.37.37.47.47 27.27.37.37.47.47.47 27.37.37.47.47.47.47 37.37.47.47.47.47.57 37.47.47.47.47.57.67 47.47.47.47.57.67.77 47.47.47.57.67.77.77 47.47.57.67.77.77.87 47.57.67.77.77.87.87 57.67.77.77.87.87.97 67.77.77.87.87.97.97 77.77.87.87.97.97 77.87.87.97.97 8.8.8 8.8.8.28 8.8.8.28.38 8.8.8.28.38.38 8.8.8.28.38.38.58 8.8.28.38.38.58.58 8.28.38.38.58.58.58 28.38.38.58.58.58.58 38.38.58.58.58.58.68 38.58.58.58.58.68.78 58.58.58.58.68.78.78 58.58.58.68.78.78.88 58.58.68.78.78.88.98 58.68.78.78.88.98.98 68.78.78.88.98.98 78.78.88.98.98 9.9.9 9.9.9.19 9.9.9.19.29 9.9.9.19.29.29 9.9.9.19.29.29.29 9.9.19.29.29.29.39 9.19.29.29.29.39.39 19.29.29.29.39.39.39 29.29.29.39.39.39.49 29.29.39.39.39.49.59 29.39.39.39.49.59.59 39.39.39.49.59.59.59 39.39.49.59.59.59.59 39.49.59.59.59.59.69 49.59.59.59.59.69.79 59.59.59.59.69.79.89 59.59.59.69.79.89.89 59.59.69.79.89.89.89 59.69.79.89.89.89.99 69.79.89.89.89.99.99 79.89.89.89.99.99.99 89.89.89.99.99.99 89.89.99.99.99} + +do_execsql_test 1.11.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING ) FROM t2 +} {0.90.40 0.90.40.30 0.90.40.30.80 0.90.40.30.80.20 0.90.40.30.80.20.90 90.40.30.80.20.90.60 40.30.80.20.90.60.70 30.80.20.90.60.70.80 80.20.90.60.70.80.90 20.90.60.70.80.90.30 90.60.70.80.90.30.50 60.70.80.90.30.50.10 70.80.90.30.50.10.30 80.90.30.50.10.30.41 90.30.50.10.30.41.81 30.50.10.30.41.81.91 50.10.30.41.81.91.61 10.30.41.81.91.61.91 30.41.81.91.61.91.91 41.81.91.61.91.91.1 81.91.61.91.91.1.81 91.61.91.91.1.81.41 61.91.91.1.81.41.61 91.91.1.81.41.61.1 91.1.81.41.61.1.21 1.81.41.61.1.21.11 81.41.61.1.21.11.51 41.61.1.21.11.51.41 61.1.21.11.51.41.31 1.21.11.51.41.31.31 21.11.51.41.31.31.11 11.51.41.31.31.11.81 51.41.31.31.11.81.91 41.31.31.11.81.91.91 31.31.11.81.91.91.21 31.11.81.91.91.21.2 11.81.91.91.21.2.62 81.91.91.21.2.62.12 91.91.21.2.62.12.32 91.21.2.62.12.32.22 21.2.62.12.32.22.42 2.62.12.32.22.42.2 62.12.32.22.42.2.72 12.32.22.42.2.72.12 32.22.42.2.72.12.22 22.42.2.72.12.22.2 42.2.72.12.22.2.72 2.72.12.22.2.72.72 72.12.22.2.72.72.12 12.22.2.72.72.12.62 22.2.72.72.12.62.52 2.72.72.12.62.52.82 72.72.12.62.52.82.23 72.12.62.52.82.23.33 12.62.52.82.23.33.93 62.52.82.23.33.93.23 52.82.23.33.93.23.93 82.23.33.93.23.93.43 23.33.93.23.93.43.3 33.93.23.93.43.3.43 93.23.93.43.3.43.33 23.93.43.3.43.33.53 93.43.3.43.33.53.63 43.3.43.33.53.63.73 3.43.33.53.63.73.13 43.33.53.63.73.13.73 33.53.63.73.13.73.73 53.63.73.13.73.73.33 63.73.13.73.73.33.93 73.13.73.73.33.93.23 13.73.73.33.93.23.13 73.73.33.93.23.13.33 73.33.93.23.13.33.3 33.93.23.13.33.3.33 93.23.13.33.3.33.83 23.13.33.3.33.83.74 13.33.3.33.83.74.74 33.3.33.83.74.74.54 3.33.83.74.74.54.84 33.83.74.74.54.84.74 83.74.74.54.84.74.24 74.74.54.84.74.24.4 74.54.84.74.24.4.94 54.84.74.24.4.94.84 84.74.24.4.94.84.74 74.24.4.94.84.74.34 24.4.94.84.74.34.34 4.94.84.74.34.34.44 94.84.74.34.34.44.74 84.74.34.34.44.74.64 74.34.34.44.74.64.14 34.34.44.74.64.14.34 34.44.74.64.14.34.84 44.74.64.14.34.84.84 74.64.14.34.84.84.44 64.14.34.84.84.44.34 14.34.84.84.44.34.65 34.84.84.44.34.65.35 84.84.44.34.65.35.85 84.44.34.65.35.85.85 44.34.65.35.85.85.55 34.65.35.85.85.55.15 65.35.85.85.55.15.25 35.85.85.55.15.25.75 85.85.55.15.25.75.95 85.55.15.25.75.95.65 55.15.25.75.95.65.65 15.25.75.95.65.65.35 25.75.95.65.65.35.5 75.95.65.65.35.5.15 95.65.65.35.5.15.95 65.65.35.5.15.95.55 65.35.5.15.95.55.75 35.5.15.95.55.75.85 5.15.95.55.75.85.75 15.95.55.75.85.75.15 95.55.75.85.75.15.95 55.75.85.75.15.95.5 75.85.75.15.95.5.26 85.75.15.95.5.26.96 75.15.95.5.26.96.46 15.95.5.26.96.46.6 95.5.26.96.46.6.46 5.26.96.46.6.46.16 26.96.46.6.46.16.16 96.46.6.46.16.16.86 46.6.46.16.16.86.56 6.46.16.16.86.56.56 46.16.16.86.56.56.56 16.16.86.56.56.56.16 16.86.56.56.56.16.36 86.56.56.56.16.36.76 56.56.56.16.36.76.96 56.56.16.36.76.96.96 56.16.36.76.96.96.26 16.36.76.96.96.26.26 36.76.96.96.26.26.36 76.96.96.26.26.36.66 96.96.26.26.36.66.36 96.26.26.36.66.36.36 26.26.36.66.36.36.97 26.36.66.36.36.97.27 36.66.36.36.97.27.97 66.36.36.97.27.97.67 36.36.97.27.97.67.77 36.97.27.97.67.77.47 97.27.97.67.77.47.7 27.97.67.77.47.7.47 97.67.77.47.7.47.87 67.77.47.7.47.87.37 77.47.7.47.87.37.87 47.7.47.87.37.87.77 7.47.87.37.87.77.7 47.87.37.87.77.7.57 87.37.87.77.7.57.47 37.87.77.7.57.47.47 87.77.7.57.47.47.37 77.7.57.47.47.37.27 7.57.47.47.37.27.17 57.47.47.37.27.17.7 47.47.37.27.17.7.38 47.37.27.17.7.38.68 37.27.17.7.38.68.78 27.17.7.38.68.78.8 17.7.38.68.78.8.28 7.38.68.78.8.28.98 38.68.78.8.28.98.78 68.78.8.28.98.78.58 78.8.28.98.78.58.98 8.28.98.78.58.98.8 28.98.78.58.98.8.88 98.78.58.98.8.88.8 78.58.98.8.88.8.58 58.98.8.88.8.58.58 98.8.88.8.58.58.58 8.88.8.58.58.58.38 88.8.58.58.58.38.99 8.58.58.58.38.99.89 58.58.58.38.99.89.59 58.58.38.99.89.59.39 58.38.99.89.59.39.99 38.99.89.59.39.99.29 99.89.59.39.99.29.59 89.59.39.99.29.59.89 59.39.99.29.59.89.89 39.99.29.59.89.89.29 99.29.59.89.89.29.9 29.59.89.89.29.9.79 59.89.89.29.9.79.49 89.89.29.9.79.49.59 89.29.9.79.49.59.29 29.9.79.49.59.29.59 9.79.49.59.29.59.19 79.49.59.29.59.19.39 49.59.29.59.19.39.9 59.29.59.19.39.9.9 29.59.19.39.9.9.99 59.19.39.9.9.99.69 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39} + +do_execsql_test 1.11.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.11.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) +} {3 74 4 74.74 5 74.74 6 74.74.99 7 74.74.99 7 74.74.99.33 7 74.99.33 7 74.99.33.89 7 99.33.89 7 99.33.89.96 7 33.89.96 7 33.89.96.38 7 89.96.38 7 89.96.38.39 7 96.38.39 7 96.38.39.91 7 38.39.91 7 38.39.91.6 7 39.91.6 7 39.91.6.97 7 91.6.97 7 91.6.97.46 7 6.97.46 7 6.97.46.54 7 97.46.54 7 97.46.54.8 7 46.54.8 7 46.54.8.29 7 54.8.29 7 54.8.29.84 7 8.29.84 7 8.29.84.23 7 29.84.23 7 29.84.23.16 7 84.23.16 7 84.23.16.65 7 23.16.65 7 23.16.65.47 7 16.65.47 7 16.65.47.86 7 65.47.86 7 65.47.86.61 7 47.86.61 7 47.86.61.85 7 86.61.85 7 86.61.85.85 7 61.85.85 7 61.85.85.59 7 85.85.59 7 85.85.59.32 7 85.59.32 7 85.59.32.3 7 59.32.3 7 59.32.3.22 7 32.3.22 7 32.3.22.55 7 3.22.55 7 3.22.55.28 7 22.55.28 7 22.55.28.25 7 55.28.25 7 55.28.25.1 7 28.25.1 7 28.25.1.40 7 25.1.40 7 25.1.40.56 7 1.40.56 7 1.40.56.75 7 40.56.75 7 40.56.75.89 7 56.75.89 7 56.75.89.76 7 75.89.76 7 75.89.76.4 7 89.76.4 7 89.76.4.42 7 76.4.42 7 76.4.42.78 7 4.42.78 7 4.42.78.29 7 42.78.29 7 42.78.29.63 7 78.29.63 7 78.29.63.87 7 29.63.87 7 29.63.87.80 7 63.87.80 7 63.87.80.72 7 87.80.72 7 87.80.72.9 7 80.72.9 7 80.72.9.73 7 72.9.73 7 72.9.73.65 7 9.73.65 7 9.73.65.58 7 73.65.58 7 73.65.58.98 7 65.58.98 7 65.58.98.21 7 58.98.21 7 58.98.21.65 7 98.21.65 7 98.21.65.5 7 21.65.5 7 21.65.5.11 7 65.5.11 7 65.5.11.87 7 5.11.87 7 5.11.87.12 7 11.87.12 7 11.87.12.20 7 87.12.20 7 87.12.20.31 7 12.20.31 7 12.20.31.95 7 20.31.95 7 20.31.95.73 7 31.95.73 7 31.95.73.88 7 95.73.88 7 95.73.88.8 7 73.88.8 7 73.88.8.49 7 88.8.49 7 88.8.49.90 7 8.49.90 7 8.49.90.96 7 49.90.96 7 49.90.96.55 7 90.96.55 7 90.96.55.77 7 96.55.77 7 96.55.77.2 7 55.77.2 7 55.77.2.85 7 77.2.85 7 77.2.85.74 7 2.85.74 7 2.85.74.70 7 85.74.70 7 85.74.70.19 7 74.70.19 7 74.70.19.26 7 70.19.26 7 70.19.26.47 7 19.26.47 7 19.26.47.90 7 26.47.90 7 26.47.90.58 7 47.90.58 7 47.90.58.9 7 90.58.9 7 90.58.9.72 7 58.9.72 7 58.9.72.33 7 9.72.33 7 9.72.33.75 7 72.33.75 7 72.33.75.81 7 33.75.81 7 33.75.81.23 7 75.81.23 7 75.81.23.13 7 81.23.13 7 81.23.13.14 7 23.13.14 7 23.13.14.91 7 13.14.91 7 13.14.91.91 7 14.91.91 7 14.91.91.15 7 91.91.15 7 91.91.15.36 7 91.15.36 7 91.15.36.3 7 15.36.3 7 15.36.3.69 7 36.3.69 7 36.3.69.52 7 3.69.52 7 3.69.52.50 7 69.52.50 7 69.52.50.10 7 52.50.10 7 52.50.10.33 7 50.10.33 7 50.10.33.39 7 10.33.39 7 10.33.39.58 7 33.39.58 7 33.39.58.38 7 39.58.38 7 39.58.38.83 7 58.38.83 7 58.38.83.82 7 38.83.82 7 38.83.82.7 7 83.82.7 6 83.82.7 5 82.7} + +do_execsql_test 1.11.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) +} {3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {}} + +do_execsql_test 1.11.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) +} {3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {}} + +do_execsql_test 1.11.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND 2 FOLLOWING) +} {3 89.6.29 4 89.6.29.47 5 89.6.29.47.59 6 89.6.29.47.59.28 7 89.6.29.47.59.28.75 7 6.29.47.59.28.75.78 7 29.47.59.28.75.78.72 7 47.59.28.75.78.72.98 7 59.28.75.78.72.98.87 7 28.75.78.72.98.87.73 7 75.78.72.98.87.73.96 7 78.72.98.87.73.96.74 7 72.98.87.73.96.74.90 7 98.87.73.96.74.90.75 7 87.73.96.74.90.75.91 7 73.96.74.90.75.91.69 7 96.74.90.75.91.69.39 7 74.90.75.91.69.39.7 6 90.75.91.69.39.7 5 75.91.69.39.7 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 74.96.97 4 74.96.97.84 5 74.96.97.84.86 6 74.96.97.84.86.32 7 74.96.97.84.86.32.25 7 96.97.84.86.32.25.89 7 97.84.86.32.25.89.29 7 84.86.32.25.89.29.9 7 86.32.25.89.29.9.21 7 32.25.89.29.9.21.12 7 25.89.29.9.21.12.88 7 89.29.9.21.12.88.55 7 29.9.21.12.88.55.70 7 9.21.12.88.55.70.58 7 21.12.88.55.70.58.81 7 12.88.55.70.58.81.91 7 88.55.70.58.81.91.52 7 55.70.58.81.91.52.58 6 70.58.81.91.52.58 5 58.81.91.52.58 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 74.38.46 4 74.38.46.23 5 74.38.46.23.61 6 74.38.46.23.61.3 7 74.38.46.23.61.3.1 7 38.46.23.61.3.1.76 7 46.23.61.3.1.76.63 7 23.61.3.1.76.63.73 7 61.3.1.76.63.73.65 7 3.1.76.63.73.65.20 7 1.76.63.73.65.20.8 7 76.63.73.65.20.8.77 7 63.73.65.20.8.77.19 7 73.65.20.8.77.19.9 7 65.20.8.77.19.9.23 7 20.8.77.19.9.23.15 7 8.77.19.9.23.15.50 7 77.19.9.23.15.50.38 6 19.9.23.15.50.38 5 9.23.15.50.38 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 99.39.54 4 99.39.54.16 5 99.39.54.16.85 6 99.39.54.16.85.22 7 99.39.54.16.85.22.40 7 39.54.16.85.22.40.4 7 54.16.85.22.40.4.87 7 16.85.22.40.4.87.65 7 85.22.40.4.87.65.5 7 22.40.4.87.65.5.31 7 40.4.87.65.5.31.49 7 4.87.65.5.31.49.2 7 87.65.5.31.49.2.26 7 65.5.31.49.2.26.72 7 5.31.49.2.26.72.13 7 31.49.2.26.72.13.36 7 49.2.26.72.13.36.10 7 2.26.72.13.36.10.83 6 26.72.13.36.10.83 5 72.13.36.10.83 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {} 3 33.91.8 4 33.91.8.65 5 33.91.8.65.85 6 33.91.8.65.85.55 7 33.91.8.65.85.55.56 7 91.8.65.85.55.56.42 7 8.65.85.55.56.42.80 7 65.85.55.56.42.80.58 7 85.55.56.42.80.58.11 7 55.56.42.80.58.11.95 7 56.42.80.58.11.95.90 7 42.80.58.11.95.90.85 7 80.58.11.95.90.85.47 7 58.11.95.90.85.47.33 7 11.95.90.85.47.33.14 7 95.90.85.47.33.14.3 7 90.85.47.33.14.3.33 7 85.47.33.14.3.33.82 6 47.33.14.3.33.82 5 33.14.3.33.82 3 {} 4 {} 5 {} 6 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 7 {} 6 {} 5 {}} + +do_execsql_test 1.12.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {74 99 99 99 99 99 89 96 96 96 96 96 68 91 91 91 99 99 99 99 99 97 97 97 97 97 97 93 93 93 93 84 93 93 93 93 93 86 86 86 91 91 91 91 91 85 85 85 59 59 91 91 91 91 91 90 90 89 89 89 89 56 56 56 56 75 75 89 98 98 98 98 98 94 94 94 94 78 78 78 63 87 87 87 87 87 84 84 84 73 95 95 95 95 96 98 98 98 98 98 74 74 74 73 73 87 87 87 87 87 41 31 31 95 95 95 95 95 88 88 88 88 49 90 90 96 96 96 96 96 77 77 77 85 85 85 85 85 74 74 70 70 59 47 80 90 90 90 90 90 72 72 72 72 93 93 93 93 93 81 81 81 37 37 62 91 91 91 91 91 91 91 99 99 99 99 99 95 95 69 84 84 84 84 84 84 84 58 58 58 58 83 83 83 83 83 82 82 17 7 5} + +do_execsql_test 1.12.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 23 23 23 2 2 2 2 2 38 38 38 38 38 39 6 6 6 6 6 27 27 27 8 8 8 8 8 29 23 16 16 16 16 16 16 7 7 7 7 7 61 24 24 24 24 12 12 12 3 3 3 3 3 15 15 15 15 15 1 1 1 1 1 16 16 16 16 16 36 36 4 4 4 4 4 30 29 29 29 2 2 2 2 2 37 37 9 9 9 9 9 13 13 13 13 1 1 1 1 1 5 5 5 5 5 11 11 8 8 8 8 8 15 15 15 15 22 22 8 8 8 8 8 11 34 34 55 55 55 44 2 2 2 2 2 7 29 29 19 19 19 19 19 26 26 26 36 36 9 9 9 9 9 33 33 33 33 9 9 9 9 9 12 12 12 12 14 33 15 15 15 15 3 3 3 3 3 30 30 30 10 10 10 10 10 21 21 21 30 30 30 27 27 17 7 5 5 5 5 5} + +do_execsql_test 1.12.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.12.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.12.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.12.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.12.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.12.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.12.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.12.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.12.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.12.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.12.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.12.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.12.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.12.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.12.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.12.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.12.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.12.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.12.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206 206 206 206 206} + +do_execsql_test 1.12.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {168 134 218 191 212 229 240 213 234 196 223 223 223 223 223 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 210 210 210 210 78 120 87 162 124 141 138 227 228 179 231 234 280 280 280 280 280 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 279 279 279 279 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 229 229 229 229 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 206 206 206 206 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 212 212 212 212 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 207 207 207 207 88 171 158 156 198 121 210 132 210 239 250 232 232 232 232 232 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229 229 229} + +do_execsql_test 1.12.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276 276 276 276 276} + +do_execsql_test 1.12.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {213 223 106 234 191 212 168 229 147 218 240 240 240 240 240 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 263 263 263 263 124 179 78 141 84 120 234 79 231 162 227 228 280 280 280 280 280 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 252 252 252 252 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 171 171 171 171 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 274 274 274 274 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 226 226 226 226 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 124 124 124 124 52 232 156 210 239 250 83 103 158 210 171 198 198 198 198 198 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276 276 276 276 276} + +do_execsql_test 1.12.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229 229 229} + +do_execsql_test 1.12.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.12.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} {} {} 56 {} {} {} {} {} {} {} {} {} {} {} 78 {} {} {} {} {} {} {} {} 37 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} {} {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 13 23 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} {} {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.12.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.12.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99} + +do_execsql_test 1.12.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 10 20 30 30 30 40 50 60 70 80 80 90 90 90 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 2 2 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 8 8 8 28 38 38 58 58 58 58 68 78 78 88 98 98 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99} + +do_execsql_test 1.12.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.12.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.12.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.12.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.12.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.12.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.12.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.12.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0.74.41.74.23 74.41.74.23.99 41.74.23.99.26 74.23.99.26.33 23.99.26.33.2 99.26.33.2.89 26.33.2.89.81 33.2.89.81.96 2.89.81.96.59 89.81.96.59.38 81.96.59.38.68 96.59.38.68.39 59.38.68.39.62 38.68.39.62.91 68.39.62.91.46 39.62.91.46.6 62.91.46.6.99 91.46.6.99.97 46.6.99.97.27 6.99.97.27.46 99.97.27.46.78 97.27.46.78.54 27.46.78.54.97 46.78.54.97.8 78.54.97.8.67 54.97.8.67.29 97.8.67.29.93 8.67.29.93.84 67.29.93.84.77 29.93.84.77.23 93.84.77.23.16 84.77.23.16.16 77.23.16.16.93 23.16.16.93.65 16.16.93.65.35 16.93.65.35.47 93.65.35.47.7 65.35.47.7.86 35.47.7.86.74 47.7.86.74.61 7.86.74.61.91 86.74.61.91.85 74.61.91.85.24 61.91.85.24.85 91.85.24.85.43 85.24.85.43.59 24.85.43.59.12 85.43.59.12.32 43.59.12.32.56 59.12.32.56.3 12.32.56.3.91 32.56.3.91.22 56.3.91.22.90 3.91.22.90.55 91.22.90.55.15 22.90.55.15.28 90.55.15.28.89 55.15.28.89.25 15.28.89.25.47 28.89.25.47.1 89.25.47.1.56 25.47.1.56.40 47.1.56.40.43 1.56.40.43.56 56.40.43.56.16 40.43.56.16.75 43.56.16.75.36 56.16.75.36.89 16.75.36.89.98 75.36.89.98.76 36.89.98.76.81 89.98.76.81.4 98.76.81.4.94 76.81.4.94.42 81.4.94.42.30 4.94.42.30.78 94.42.30.78.33 42.30.78.33.29 30.78.33.29.53 78.33.29.53.63 33.29.53.63.2 29.53.63.2.87 53.63.2.87.37 63.2.87.37.80 2.87.37.80.84 87.37.80.84.72 37.80.84.72.41 80.84.72.41.9 84.72.41.9.61 72.41.9.61.73 41.9.61.73.95 9.61.73.95.65 61.73.95.65.13 73.95.65.13.58 95.65.13.58.96 65.13.58.96.98 13.58.96.98.1 58.96.98.1.21 96.98.1.21.74 98.1.21.74.65 1.21.74.65.35 21.74.65.35.5 74.65.35.5.73 65.35.5.73.11 35.5.73.11.51 5.73.11.51.87 73.11.51.87.41 11.51.87.41.12 51.87.41.12.8 87.41.12.8.20 41.12.8.20.31 12.8.20.31.31 8.20.31.31.15 20.31.31.15.95 31.31.15.95.22 31.15.95.22.73 15.95.22.73.79 95.22.73.79.88 22.73.79.88.34 73.79.88.34.8 79.88.34.8.11 88.34.8.11.49 34.8.11.49.34 8.11.49.34.90 11.49.34.90.59 49.34.90.59.96 34.90.59.96.60 90.59.96.60.55 59.96.60.55.75 96.60.55.75.77 60.55.75.77.44 55.75.77.44.2 75.77.44.2.7 77.44.2.7.85 44.2.7.85.57 2.7.85.57.74 7.85.57.74.29 85.57.74.29.70 57.74.29.70.59 74.29.70.59.19 29.70.59.19.39 70.59.19.39.26 59.19.39.26.26 19.39.26.26.47 39.26.26.47.80 26.26.47.80.90 26.47.80.90.36 47.80.90.36.58 80.90.36.58.47 90.36.58.47.9 36.58.47.9.72 58.47.9.72.72 47.9.72.72.66 9.72.72.66.33 72.72.66.33.93 72.66.33.93.75 66.33.93.75.64 33.93.75.64.81 93.75.64.81.9 75.64.81.9.23 64.81.9.23.37 81.9.23.37.13 9.23.37.13.12 23.37.13.12.14 37.13.12.14.62 13.12.14.62.91 12.14.62.91.36 14.62.91.36.91 62.91.36.91.33 91.36.91.33.15 36.91.33.15.34 91.33.15.34.36 33.15.34.36.99 15.34.36.99.3 34.36.99.3.95 36.99.3.95.69 99.3.95.69.58 3.95.69.58.52 95.69.58.52.30 69.58.52.30.50 58.52.30.50.84 52.30.50.84.10 30.50.84.10.84 50.84.10.84.33 84.10.84.33.21 10.84.33.21.39 84.33.21.39.44 33.21.39.44.58 21.39.44.58.30 39.44.58.30.38 44.58.30.38.34 58.30.38.34.83 30.38.34.83.27 38.34.83.27.82 34.83.27.82.17 83.27.82.17.7 27.82.17.7.5 82.17.7.5 17.7.5 7.5 5} + +do_execsql_test 1.12.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0.90.40.30.80 90.40.30.80.20 40.30.80.20.90 30.80.20.90.60 80.20.90.60.70 20.90.60.70.80 90.60.70.80.90 60.70.80.90.30 70.80.90.30.50 80.90.30.50.10 90.30.50.10.30 30.50.10.30 50.10.30 10.30 30 41.81.91.61.91 81.91.61.91.91 91.61.91.91.1 61.91.91.1.81 91.91.1.81.41 91.1.81.41.61 1.81.41.61.1 81.41.61.1.21 41.61.1.21.11 61.1.21.11.51 1.21.11.51.41 21.11.51.41.31 11.51.41.31.31 51.41.31.31.11 41.31.31.11.81 31.31.11.81.91 31.11.81.91.91 11.81.91.91.21 81.91.91.21 91.91.21 91.21 21 2.62.12.32.22 62.12.32.22.42 12.32.22.42.2 32.22.42.2.72 22.42.2.72.12 42.2.72.12.22 2.72.12.22.2 72.12.22.2.72 12.22.2.72.72 22.2.72.72.12 2.72.72.12.62 72.72.12.62.52 72.12.62.52.82 12.62.52.82 62.52.82 52.82 82 23.33.93.23.93 33.93.23.93.43 93.23.93.43.3 23.93.43.3.43 93.43.3.43.33 43.3.43.33.53 3.43.33.53.63 43.33.53.63.73 33.53.63.73.13 53.63.73.13.73 63.73.13.73.73 73.13.73.73.33 13.73.73.33.93 73.73.33.93.23 73.33.93.23.13 33.93.23.13.33 93.23.13.33.3 23.13.33.3.33 13.33.3.33.83 33.3.33.83 3.33.83 33.83 83 74.74.54.84.74 74.54.84.74.24 54.84.74.24.4 84.74.24.4.94 74.24.4.94.84 24.4.94.84.74 4.94.84.74.34 94.84.74.34.34 84.74.34.34.44 74.34.34.44.74 34.34.44.74.64 34.44.74.64.14 44.74.64.14.34 74.64.14.34.84 64.14.34.84.84 14.34.84.84.44 34.84.84.44.34 84.84.44.34 84.44.34 44.34 34 65.35.85.85.55 35.85.85.55.15 85.85.55.15.25 85.55.15.25.75 55.15.25.75.95 15.25.75.95.65 25.75.95.65.65 75.95.65.65.35 95.65.65.35.5 65.65.35.5.15 65.35.5.15.95 35.5.15.95.55 5.15.95.55.75 15.95.55.75.85 95.55.75.85.75 55.75.85.75.15 75.85.75.15.95 85.75.15.95.5 75.15.95.5 15.95.5 95.5 5 26.96.46.6.46 96.46.6.46.16 46.6.46.16.16 6.46.16.16.86 46.16.16.86.56 16.16.86.56.56 16.86.56.56.56 86.56.56.56.16 56.56.56.16.36 56.56.16.36.76 56.16.36.76.96 16.36.76.96.96 36.76.96.96.26 76.96.96.26.26 96.96.26.26.36 96.26.26.36.66 26.26.36.66.36 26.36.66.36.36 36.66.36.36 66.36.36 36.36 36 97.27.97.67.77 27.97.67.77.47 97.67.77.47.7 67.77.47.7.47 77.47.7.47.87 47.7.47.87.37 7.47.87.37.87 47.87.37.87.77 87.37.87.77.7 37.87.77.7.57 87.77.7.57.47 77.7.57.47.47 7.57.47.47.37 57.47.47.37.27 47.47.37.27.17 47.37.27.17.7 37.27.17.7 27.17.7 17.7 7 38.68.78.8.28 68.78.8.28.98 78.8.28.98.78 8.28.98.78.58 28.98.78.58.98 98.78.58.98.8 78.58.98.8.88 58.98.8.88.8 98.8.88.8.58 8.88.8.58.58 88.8.58.58.58 8.58.58.58.38 58.58.58.38 58.58.38 58.38 38 99.89.59.39.99 89.59.39.99.29 59.39.99.29.59 39.99.29.59.89 99.29.59.89.89 29.59.89.89.29 59.89.89.29.9 89.89.29.9.79 89.29.9.79.49 29.9.79.49.59 9.79.49.59.29 79.49.59.29.59 49.59.29.59.19 59.29.59.19.39 29.59.19.39.9 59.19.39.9.9 19.39.9.9.99 39.9.9.99.69 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39} + +do_execsql_test 1.12.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0.1.1.2.2 1.1.2.2.2 1.2.2.2.3 2.2.2.3.3 2.2.3.3.4 2.3.3.4.5 3.3.4.5.5 3.4.5.5.6 4.5.5.6.7 5.5.6.7.7 5.6.7.7.7 6.7.7.7.8 7.7.7.8.8 7.7.8.8.8 7.8.8.8.9 8.8.8.9.9 8.8.9.9.9 8.9.9.9.10 9.9.9.10.11 9.9.10.11.11 9.10.11.11.12 10.11.11.12.12 11.11.12.12.12 11.12.12.12.13 12.12.12.13.13 12.12.13.13.14 12.13.13.14.15 13.13.14.15.15 13.14.15.15.15 14.15.15.15.16 15.15.15.16.16 15.15.16.16.16 15.16.16.16.17 16.16.16.17.19 16.16.17.19.20 16.17.19.20.21 17.19.20.21.21 19.20.21.21.22 20.21.21.22.22 21.21.22.22.23 21.22.22.23.23 22.22.23.23.23 22.23.23.23.24 23.23.23.24.25 23.23.24.25.26 23.24.25.26.26 24.25.26.26.26 25.26.26.26.27 26.26.26.27.27 26.26.27.27.28 26.27.27.28.29 27.27.28.29.29 27.28.29.29.29 28.29.29.29.30 29.29.29.30.30 29.29.30.30.30 29.30.30.30.31 30.30.30.31.31 30.30.31.31.32 30.31.31.32.33 31.31.32.33.33 31.32.33.33.33 32.33.33.33.33 33.33.33.33.33 33.33.33.33.34 33.33.33.34.34 33.33.34.34.34 33.34.34.34.34 34.34.34.34.35 34.34.34.35.35 34.34.35.35.36 34.35.35.36.36 35.35.36.36.36 35.36.36.36.36 36.36.36.36.37 36.36.36.37.37 36.36.37.37.38 36.37.37.38.38 37.37.38.38.39 37.38.38.39.39 38.38.39.39.39 38.39.39.39.40 39.39.39.40.41 39.39.40.41.41 39.40.41.41.41 40.41.41.41.42 41.41.41.42.43 41.41.42.43.43 41.42.43.43.44 42.43.43.44.44 43.43.44.44.46 43.44.44.46.46 44.44.46.46.47 44.46.46.47.47 46.46.47.47.47 46.47.47.47.47 47.47.47.47.49 47.47.47.49.50 47.47.49.50.51 47.49.50.51.52 49.50.51.52.53 50.51.52.53.54 51.52.53.54.55 52.53.54.55.55 53.54.55.55.56 54.55.55.56.56 55.55.56.56.56 55.56.56.56.57 56.56.56.57.58 56.56.57.58.58 56.57.58.58.58 57.58.58.58.58 58.58.58.58.59 58.58.58.59.59 58.58.59.59.59 58.59.59.59.59 59.59.59.59.60 59.59.59.60.61 59.59.60.61.61 59.60.61.61.62 60.61.61.62.62 61.61.62.62.63 61.62.62.63.64 62.62.63.64.65 62.63.64.65.65 63.64.65.65.65 64.65.65.65.66 65.65.65.66.67 65.65.66.67.68 65.66.67.68.69 66.67.68.69.70 67.68.69.70.72 68.69.70.72.72 69.70.72.72.72 70.72.72.72.73 72.72.72.73.73 72.72.73.73.73 72.73.73.73.74 73.73.73.74.74 73.73.74.74.74 73.74.74.74.74 74.74.74.74.74 74.74.74.74.75 74.74.74.75.75 74.74.75.75.75 74.75.75.75.76 75.75.75.76.77 75.75.76.77.77 75.76.77.77.78 76.77.77.78.78 77.77.78.78.79 77.78.78.79.80 78.78.79.80.80 78.79.80.80.81 79.80.80.81.81 80.80.81.81.81 80.81.81.81.82 81.81.81.82.83 81.81.82.83.84 81.82.83.84.84 82.83.84.84.84 83.84.84.84.84 84.84.84.84.85 84.84.84.85.85 84.84.85.85.85 84.85.85.85.86 85.85.85.86.87 85.85.86.87.87 85.86.87.87.88 86.87.87.88.89 87.87.88.89.89 87.88.89.89.89 88.89.89.89.90 89.89.89.90.90 89.89.90.90.90 89.90.90.90.91 90.90.90.91.91 90.90.91.91.91 90.91.91.91.91 91.91.91.91.91 91.91.91.91.93 91.91.91.93.93 91.91.93.93.93 91.93.93.93.94 93.93.93.94.95 93.93.94.95.95 93.94.95.95.95 94.95.95.95.96 95.95.95.96.96 95.95.96.96.96 95.96.96.96.97 96.96.96.97.97 96.96.97.97.98 96.97.97.98.98 97.97.98.98.99 97.98.98.99.99 98.98.99.99.99 98.99.99.99 99.99.99 99.99 99} + +do_execsql_test 1.12.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0.10.20.30.30 10.20.30.30.30 20.30.30.30.40 30.30.30.40.50 30.30.40.50.60 30.40.50.60.70 40.50.60.70.80 50.60.70.80.80 60.70.80.80.90 70.80.80.90.90 80.80.90.90.90 80.90.90.90 90.90.90 90.90 90 1.1.11.11.21 1.11.11.21.21 11.11.21.21.31 11.21.21.31.31 21.21.31.31.41 21.31.31.41.41 31.31.41.41.41 31.41.41.41.51 41.41.41.51.61 41.41.51.61.61 41.51.61.61.81 51.61.61.81.81 61.61.81.81.81 61.81.81.81.91 81.81.81.91.91 81.81.91.91.91 81.91.91.91.91 91.91.91.91.91 91.91.91.91 91.91.91 91.91 91 2.2.2.12.12 2.2.12.12.12 2.12.12.12.22 12.12.12.22.22 12.12.22.22.32 12.22.22.32.42 22.22.32.42.52 22.32.42.52.62 32.42.52.62.62 42.52.62.62.72 52.62.62.72.72 62.62.72.72.72 62.72.72.72.82 72.72.72.82 72.72.82 72.82 82 3.3.13.13.23 3.13.13.23.23 13.13.23.23.23 13.23.23.23.33 23.23.23.33.33 23.23.33.33.33 23.33.33.33.33 33.33.33.33.33 33.33.33.33.43 33.33.33.43.43 33.33.43.43.53 33.43.43.53.63 43.43.53.63.73 43.53.63.73.73 53.63.73.73.73 63.73.73.73.83 73.73.73.83.93 73.73.83.93.93 73.83.93.93.93 83.93.93.93 93.93.93 93.93 93 4.14.24.34.34 14.24.34.34.34 24.34.34.34.34 34.34.34.34.44 34.34.34.44.44 34.34.44.44.54 34.44.44.54.64 44.44.54.64.74 44.54.64.74.74 54.64.74.74.74 64.74.74.74.74 74.74.74.74.74 74.74.74.74.84 74.74.74.84.84 74.74.84.84.84 74.84.84.84.84 84.84.84.84.94 84.84.84.94 84.84.94 84.94 94 5.5.15.15.15 5.15.15.15.25 15.15.15.25.35 15.15.25.35.35 15.25.35.35.55 25.35.35.55.55 35.35.55.55.65 35.55.55.65.65 55.55.65.65.65 55.65.65.65.75 65.65.65.75.75 65.65.75.75.75 65.75.75.75.85 75.75.75.85.85 75.75.85.85.85 75.85.85.85.95 85.85.85.95.95 85.85.95.95.95 85.95.95.95 95.95.95 95.95 95 6.16.16.16.26 16.16.16.26.26 16.16.26.26.26 16.26.26.26.36 26.26.26.36.36 26.26.36.36.36 26.36.36.36.36 36.36.36.36.46 36.36.36.46.46 36.36.46.46.56 36.46.46.56.56 46.46.56.56.56 46.56.56.56.66 56.56.56.66.76 56.56.66.76.86 56.66.76.86.96 66.76.86.96.96 76.86.96.96.96 86.96.96.96 96.96.96 96.96 96 7.7.7.17.27 7.7.17.27.27 7.17.27.27.37 17.27.27.37.37 27.27.37.37.47 27.37.37.47.47 37.37.47.47.47 37.47.47.47.47 47.47.47.47.57 47.47.47.57.67 47.47.57.67.77 47.57.67.77.77 57.67.77.77.87 67.77.77.87.87 77.77.87.87.97 77.87.87.97.97 87.87.97.97 87.97.97 97.97 97 8.8.8.28.38 8.8.28.38.38 8.28.38.38.58 28.38.38.58.58 38.38.58.58.58 38.58.58.58.58 58.58.58.58.68 58.58.58.68.78 58.58.68.78.78 58.68.78.78.88 68.78.78.88.98 78.78.88.98.98 78.88.98.98 88.98.98 98.98 98 9.9.9.19.29 9.9.19.29.29 9.19.29.29.29 19.29.29.29.39 29.29.29.39.39 29.29.39.39.39 29.39.39.39.49 39.39.39.49.59 39.39.49.59.59 39.49.59.59.59 49.59.59.59.59 59.59.59.59.69 59.59.59.69.79 59.59.69.79.89 59.69.79.89.89 69.79.89.89.89 79.89.89.89.99 89.89.89.99.99 89.89.99.99.99 89.99.99.99 99.99.99 99.99 99} + +do_execsql_test 1.12.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING ) FROM t2 +} {0.90.40.30.80 90.40.30.80.20 40.30.80.20.90 30.80.20.90.60 80.20.90.60.70 20.90.60.70.80 90.60.70.80.90 60.70.80.90.30 70.80.90.30.50 80.90.30.50.10 90.30.50.10.30 30.50.10.30.41 50.10.30.41.81 10.30.41.81.91 30.41.81.91.61 41.81.91.61.91 81.91.61.91.91 91.61.91.91.1 61.91.91.1.81 91.91.1.81.41 91.1.81.41.61 1.81.41.61.1 81.41.61.1.21 41.61.1.21.11 61.1.21.11.51 1.21.11.51.41 21.11.51.41.31 11.51.41.31.31 51.41.31.31.11 41.31.31.11.81 31.31.11.81.91 31.11.81.91.91 11.81.91.91.21 81.91.91.21.2 91.91.21.2.62 91.21.2.62.12 21.2.62.12.32 2.62.12.32.22 62.12.32.22.42 12.32.22.42.2 32.22.42.2.72 22.42.2.72.12 42.2.72.12.22 2.72.12.22.2 72.12.22.2.72 12.22.2.72.72 22.2.72.72.12 2.72.72.12.62 72.72.12.62.52 72.12.62.52.82 12.62.52.82.23 62.52.82.23.33 52.82.23.33.93 82.23.33.93.23 23.33.93.23.93 33.93.23.93.43 93.23.93.43.3 23.93.43.3.43 93.43.3.43.33 43.3.43.33.53 3.43.33.53.63 43.33.53.63.73 33.53.63.73.13 53.63.73.13.73 63.73.13.73.73 73.13.73.73.33 13.73.73.33.93 73.73.33.93.23 73.33.93.23.13 33.93.23.13.33 93.23.13.33.3 23.13.33.3.33 13.33.3.33.83 33.3.33.83.74 3.33.83.74.74 33.83.74.74.54 83.74.74.54.84 74.74.54.84.74 74.54.84.74.24 54.84.74.24.4 84.74.24.4.94 74.24.4.94.84 24.4.94.84.74 4.94.84.74.34 94.84.74.34.34 84.74.34.34.44 74.34.34.44.74 34.34.44.74.64 34.44.74.64.14 44.74.64.14.34 74.64.14.34.84 64.14.34.84.84 14.34.84.84.44 34.84.84.44.34 84.84.44.34.65 84.44.34.65.35 44.34.65.35.85 34.65.35.85.85 65.35.85.85.55 35.85.85.55.15 85.85.55.15.25 85.55.15.25.75 55.15.25.75.95 15.25.75.95.65 25.75.95.65.65 75.95.65.65.35 95.65.65.35.5 65.65.35.5.15 65.35.5.15.95 35.5.15.95.55 5.15.95.55.75 15.95.55.75.85 95.55.75.85.75 55.75.85.75.15 75.85.75.15.95 85.75.15.95.5 75.15.95.5.26 15.95.5.26.96 95.5.26.96.46 5.26.96.46.6 26.96.46.6.46 96.46.6.46.16 46.6.46.16.16 6.46.16.16.86 46.16.16.86.56 16.16.86.56.56 16.86.56.56.56 86.56.56.56.16 56.56.56.16.36 56.56.16.36.76 56.16.36.76.96 16.36.76.96.96 36.76.96.96.26 76.96.96.26.26 96.96.26.26.36 96.26.26.36.66 26.26.36.66.36 26.36.66.36.36 36.66.36.36.97 66.36.36.97.27 36.36.97.27.97 36.97.27.97.67 97.27.97.67.77 27.97.67.77.47 97.67.77.47.7 67.77.47.7.47 77.47.7.47.87 47.7.47.87.37 7.47.87.37.87 47.87.37.87.77 87.37.87.77.7 37.87.77.7.57 87.77.7.57.47 77.7.57.47.47 7.57.47.47.37 57.47.47.37.27 47.47.37.27.17 47.37.27.17.7 37.27.17.7.38 27.17.7.38.68 17.7.38.68.78 7.38.68.78.8 38.68.78.8.28 68.78.8.28.98 78.8.28.98.78 8.28.98.78.58 28.98.78.58.98 98.78.58.98.8 78.58.98.8.88 58.98.8.88.8 98.8.88.8.58 8.88.8.58.58 88.8.58.58.58 8.58.58.58.38 58.58.58.38.99 58.58.38.99.89 58.38.99.89.59 38.99.89.59.39 99.89.59.39.99 89.59.39.99.29 59.39.99.29.59 39.99.29.59.89 99.29.59.89.89 29.59.89.89.29 59.89.89.29.9 89.89.29.9.79 89.29.9.79.49 29.9.79.49.59 9.79.49.59.29 79.49.59.29.59 49.59.29.59.19 59.29.59.19.39 29.59.19.39.9 59.19.39.9.9 19.39.9.9.99 39.9.9.99.69 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39} + +do_execsql_test 1.12.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.12.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) +} {5 74.74 5 74.74.99 5 74.99 5 74.99.33 5 99.33 5 99.33.89 5 33.89 5 33.89.96 5 89.96 5 89.96.38 5 96.38 5 96.38.39 5 38.39 5 38.39.91 5 39.91 5 39.91.6 5 91.6 5 91.6.97 5 6.97 5 6.97.46 5 97.46 5 97.46.54 5 46.54 5 46.54.8 5 54.8 5 54.8.29 5 8.29 5 8.29.84 5 29.84 5 29.84.23 5 84.23 5 84.23.16 5 23.16 5 23.16.65 5 16.65 5 16.65.47 5 65.47 5 65.47.86 5 47.86 5 47.86.61 5 86.61 5 86.61.85 5 61.85 5 61.85.85 5 85.85 5 85.85.59 5 85.59 5 85.59.32 5 59.32 5 59.32.3 5 32.3 5 32.3.22 5 3.22 5 3.22.55 5 22.55 5 22.55.28 5 55.28 5 55.28.25 5 28.25 5 28.25.1 5 25.1 5 25.1.40 5 1.40 5 1.40.56 5 40.56 5 40.56.75 5 56.75 5 56.75.89 5 75.89 5 75.89.76 5 89.76 5 89.76.4 5 76.4 5 76.4.42 5 4.42 5 4.42.78 5 42.78 5 42.78.29 5 78.29 5 78.29.63 5 29.63 5 29.63.87 5 63.87 5 63.87.80 5 87.80 5 87.80.72 5 80.72 5 80.72.9 5 72.9 5 72.9.73 5 9.73 5 9.73.65 5 73.65 5 73.65.58 5 65.58 5 65.58.98 5 58.98 5 58.98.21 5 98.21 5 98.21.65 5 21.65 5 21.65.5 5 65.5 5 65.5.11 5 5.11 5 5.11.87 5 11.87 5 11.87.12 5 87.12 5 87.12.20 5 12.20 5 12.20.31 5 20.31 5 20.31.95 5 31.95 5 31.95.73 5 95.73 5 95.73.88 5 73.88 5 73.88.8 5 88.8 5 88.8.49 5 8.49 5 8.49.90 5 49.90 5 49.90.96 5 90.96 5 90.96.55 5 96.55 5 96.55.77 5 55.77 5 55.77.2 5 77.2 5 77.2.85 5 2.85 5 2.85.74 5 85.74 5 85.74.70 5 74.70 5 74.70.19 5 70.19 5 70.19.26 5 19.26 5 19.26.47 5 26.47 5 26.47.90 5 47.90 5 47.90.58 5 90.58 5 90.58.9 5 58.9 5 58.9.72 5 9.72 5 9.72.33 5 72.33 5 72.33.75 5 33.75 5 33.75.81 5 75.81 5 75.81.23 5 81.23 5 81.23.13 5 23.13 5 23.13.14 5 13.14 5 13.14.91 5 14.91 5 14.91.91 5 91.91 5 91.91.15 5 91.15 5 91.15.36 5 15.36 5 15.36.3 5 36.3 5 36.3.69 5 3.69 5 3.69.52 5 69.52 5 69.52.50 5 52.50 5 52.50.10 5 50.10 5 50.10.33 5 10.33 5 10.33.39 5 33.39 5 33.39.58 5 39.58 5 39.58.38 5 58.38 5 58.38.83 5 38.83 5 38.83.82 5 83.82 5 83.82.7 5 82.7 4 82.7 3 7 2 7 1 {}} + +do_execsql_test 1.12.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) +} {5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.12.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) +} {5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.12.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING) +} {5 89.6.29.47.59 5 6.29.47.59.28 5 29.47.59.28.75 5 47.59.28.75.78 5 59.28.75.78.72 5 28.75.78.72.98 5 75.78.72.98.87 5 78.72.98.87.73 5 72.98.87.73.96 5 98.87.73.96.74 5 87.73.96.74.90 5 73.96.74.90.75 5 96.74.90.75.91 5 74.90.75.91.69 5 90.75.91.69.39 5 75.91.69.39.7 4 91.69.39.7 3 69.39.7 2 39.7 1 7 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 74.96.97.84.86 5 96.97.84.86.32 5 97.84.86.32.25 5 84.86.32.25.89 5 86.32.25.89.29 5 32.25.89.29.9 5 25.89.29.9.21 5 89.29.9.21.12 5 29.9.21.12.88 5 9.21.12.88.55 5 21.12.88.55.70 5 12.88.55.70.58 5 88.55.70.58.81 5 55.70.58.81.91 5 70.58.81.91.52 5 58.81.91.52.58 4 81.91.52.58 3 91.52.58 2 52.58 1 58 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 74.38.46.23.61 5 38.46.23.61.3 5 46.23.61.3.1 5 23.61.3.1.76 5 61.3.1.76.63 5 3.1.76.63.73 5 1.76.63.73.65 5 76.63.73.65.20 5 63.73.65.20.8 5 73.65.20.8.77 5 65.20.8.77.19 5 20.8.77.19.9 5 8.77.19.9.23 5 77.19.9.23.15 5 19.9.23.15.50 5 9.23.15.50.38 4 23.15.50.38 3 15.50.38 2 50.38 1 38 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 99.39.54.16.85 5 39.54.16.85.22 5 54.16.85.22.40 5 16.85.22.40.4 5 85.22.40.4.87 5 22.40.4.87.65 5 40.4.87.65.5 5 4.87.65.5.31 5 87.65.5.31.49 5 65.5.31.49.2 5 5.31.49.2.26 5 31.49.2.26.72 5 49.2.26.72.13 5 2.26.72.13.36 5 26.72.13.36.10 5 72.13.36.10.83 4 13.36.10.83 3 36.10.83 2 10.83 1 83 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {} 5 33.91.8.65.85 5 91.8.65.85.55 5 8.65.85.55.56 5 65.85.55.56.42 5 85.55.56.42.80 5 55.56.42.80.58 5 56.42.80.58.11 5 42.80.58.11.95 5 80.58.11.95.90 5 58.11.95.90.85 5 11.95.90.85.47 5 95.90.85.47.33 5 90.85.47.33.14 5 85.47.33.14.3 5 47.33.14.3.33 5 33.14.3.33.82 4 14.3.33.82 3 3.33.82 2 33.82 1 82 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.13.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {74 99 99 99 33 89 89 96 96 96 68 68 68 91 91 91 99 99 99 97 78 78 97 97 97 67 93 93 93 84 77 23 93 93 93 65 47 86 86 86 91 91 91 85 85 85 59 59 56 56 91 91 91 90 90 55 89 89 89 47 56 56 56 56 56 75 75 89 98 98 98 81 94 94 94 78 78 78 53 63 63 87 87 87 84 84 84 72 61 73 95 95 95 65 96 98 98 98 74 74 74 65 73 73 73 87 87 87 41 20 31 31 31 95 95 95 79 88 88 88 34 49 49 90 90 96 96 96 75 77 77 77 44 85 85 85 74 74 70 70 59 39 39 47 80 90 90 90 58 58 72 72 72 72 93 93 93 81 81 81 37 37 37 14 62 91 91 91 91 91 34 36 99 99 99 95 95 69 58 52 84 84 84 84 84 39 44 58 58 58 38 83 83 83 82 82 17 7 5 {} {}} + +do_execsql_test 1.13.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {23 23 23 26 2 2 2 81 59 38 38 38 39 39 46 6 6 6 27 27 27 46 54 8 8 8 29 29 77 23 16 16 16 16 35 35 7 7 7 61 61 61 24 24 24 43 12 12 12 3 3 3 22 22 15 15 15 25 25 1 1 1 40 40 16 16 16 36 36 76 76 4 4 4 30 30 30 29 29 29 2 2 2 37 37 72 41 9 9 9 61 65 13 13 13 58 1 1 1 21 35 5 5 5 11 11 41 12 8 8 8 20 15 15 15 22 22 73 34 8 8 8 11 34 34 59 59 55 55 55 44 2 2 2 7 57 29 29 29 19 19 19 26 26 26 47 36 36 36 9 9 9 66 33 33 33 64 64 9 9 9 13 12 12 12 14 36 36 33 15 15 15 34 3 3 3 58 52 30 30 30 10 10 10 21 21 21 39 30 30 30 34 27 27 17 7 5 5 5 {} {}} + +do_execsql_test 1.13.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.13.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.13.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.13.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.13.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.13.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.13.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.13.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.13.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.13.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.13.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.13.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.13.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.13.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.13.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.13.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.13.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.13.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.13.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {28 105 33 41 11 99 92 108 72 52 83 55 79 109 65 26 120 119 50 70 103 80 124 36 96 59 124 116 110 57 51 52 130 103 74 87 48 128 117 105 136 131 71 133 92 109 63 84 109 57 146 78 147 113 74 88 150 87 110 65 121 106 110 124 85 145 107 161 171 150 156 80 171 120 109 158 114 111 136 147 87 173 124 168 173 162 132 101 154 167 190 161 110 156 195 198 102 123 177 169 140 111 180 119 160 197 152 124 121 134 146 147 132 213 141 193 200 210 157 132 136 175 161 218 188 226 191 187 208 211 179 138 144 223 196 214 170 212 202 163 184 172 173 195 229 240 187 210 200 163 227 228 223 191 252 235 225 243 172 187 202 179 179 182 231 261 207 263 206 189 209 212 276 181 274 249 239 234 213 234 269 196 271 221 210 229 235 250 223 232 229 279 224 280 216 207 206 206 206 {} {}} + +do_execsql_test 1.13.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {168 134 218 191 212 229 240 213 234 196 223 223 223 {} {} 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 210 210 {} {} 78 120 87 162 124 141 138 227 228 179 231 234 280 280 280 {} {} 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 279 279 {} {} 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 229 229 {} {} 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 206 206 {} {} 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 212 212 {} {} 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 207 207 {} {} 88 171 158 156 198 121 210 132 210 239 250 232 232 232 {} {} 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229 {} {}} + +do_execsql_test 1.13.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {87 138 57 181 80 111 206 26 48 144 207 36 121 132 101 163 172 196 119 136 63 124 179 110 179 182 74 132 189 51 52 85 216 163 134 123 210 78 141 28 57 187 71 87 33 172 173 50 224 88 59 111 170 109 213 223 146 147 84 41 114 191 206 221 157 161 209 229 74 140 107 187 207 212 124 202 52 232 55 184 229 106 44 132 152 120 92 110 179 235 65 70 87 110 195 200 175 234 160 234 136 80 113 187 109 121 124 196 156 210 239 250 72 109 188 202 191 105 154 79 231 147 225 103 161 169 223 96 83 249 212 162 227 228 167 180 193 76 78 117 177 214 145 208 235 150 110 211 103 158 200 168 229 92 156 243 280 279 116 173 269 271 131 133 223 128 173 197 210 99 150 161 147 218 240 109 136 146 261 263 124 130 252 171 190 213 274 108 195 226 119 124 171 198 105 120 276 276 276 {} {}} + +do_execsql_test 1.13.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {213 223 106 234 191 212 168 229 147 218 240 240 240 {} {} 123 210 146 147 44 132 152 160 105 154 92 156 243 109 136 146 261 263 263 263 {} {} 124 179 78 141 84 120 234 79 231 162 227 228 280 280 280 {} {} 28 57 187 41 114 191 206 221 92 110 136 147 167 180 193 279 124 130 252 252 252 {} {} 161 209 229 179 235 80 225 76 78 117 177 214 116 173 269 271 171 171 171 {} {} 189 87 74 140 113 187 103 161 169 145 208 235 131 133 223 190 213 274 274 274 {} {} 33 172 173 107 187 207 212 65 70 109 121 124 223 150 128 108 195 226 226 226 {} {} 50 224 124 202 87 110 195 200 196 96 110 211 173 197 119 124 124 124 {} {} 52 232 156 210 239 250 83 103 158 210 171 198 198 198 {} {} 59 111 170 55 184 229 175 72 109 188 202 249 200 99 150 161 105 120 276 276 276 {} {}} + +do_execsql_test 1.13.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {168 134 218 191 212 229 240 213 234 196 223 44 92 109 105 136 146 65 156 132 154 102 123 119 160 152 146 147 136 243 261 263 210 11 79 63 84 78 120 87 162 124 141 138 227 228 179 231 234 280 28 41 124 57 130 92 57 110 114 136 147 167 110 180 193 191 252 187 179 206 181 221 279 76 78 80 116 117 71 80 171 173 177 157 161 179 214 225 182 209 269 271 235 229 103 74 131 133 113 74 87 145 190 161 169 140 111 132 213 187 208 223 235 189 274 206 33 108 65 26 70 51 52 128 109 121 124 85 107 150 195 226 172 173 187 223 207 212 119 50 124 96 110 87 48 110 173 124 197 211 144 196 195 200 202 224 216 207 52 83 103 36 88 171 158 156 198 121 210 132 210 239 250 232 105 99 72 55 120 59 109 150 161 111 101 200 175 188 170 202 163 184 163 172 276 249 229 229 229 {} {}} + +do_execsql_test 1.13.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {41 {} {} {} {} {} {} {} 59 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 43 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 84 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 65 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {40 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 51 {} {} {} {} {} {} {} {} {} {} {} 22 {} {} {} {} {} 2 {} {} {} 62 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 2 3 4 5 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {20 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 11 21 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 12 12 22 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {40 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 51 {} {} {} {} {} {} {} {} {} {} {} 22 {} {} {} {} {} 2 {} {} {} 62 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5 {} {}} + +do_execsql_test 1.13.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {40 30 80 20 90 60 70 80 90 30 50 10 30 {} {} 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 {} {} 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 {} {} 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 {} {} 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 {} {} 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 {} {} 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 {} {} 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 {} {} 78 8 28 98 78 58 98 8 88 8 58 58 58 38 {} {} 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39 {} {}} + +do_execsql_test 1.13.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99 {} {}} + +do_execsql_test 1.13.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {20 30 30 30 40 50 60 70 80 80 90 90 90 {} {} 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 {} {} 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 {} {} 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 {} {} 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 {} {} 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 {} {} 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 {} {} 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 {} {} 8 28 38 38 58 58 58 58 68 78 78 88 98 98 {} {} 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99 {} {}} + +do_execsql_test 1.13.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39 {} {}} + +do_execsql_test 1.13.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.13.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.13.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.13.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.13.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {41.74.23 74.23.99 23.99.26 99.26.33 26.33.2 33.2.89 2.89.81 89.81.96 81.96.59 96.59.38 59.38.68 38.68.39 68.39.62 39.62.91 62.91.46 91.46.6 46.6.99 6.99.97 99.97.27 97.27.46 27.46.78 46.78.54 78.54.97 54.97.8 97.8.67 8.67.29 67.29.93 29.93.84 93.84.77 84.77.23 77.23.16 23.16.16 16.16.93 16.93.65 93.65.35 65.35.47 35.47.7 47.7.86 7.86.74 86.74.61 74.61.91 61.91.85 91.85.24 85.24.85 24.85.43 85.43.59 43.59.12 59.12.32 12.32.56 32.56.3 56.3.91 3.91.22 91.22.90 22.90.55 90.55.15 55.15.28 15.28.89 28.89.25 89.25.47 25.47.1 47.1.56 1.56.40 56.40.43 40.43.56 43.56.16 56.16.75 16.75.36 75.36.89 36.89.98 89.98.76 98.76.81 76.81.4 81.4.94 4.94.42 94.42.30 42.30.78 30.78.33 78.33.29 33.29.53 29.53.63 53.63.2 63.2.87 2.87.37 87.37.80 37.80.84 80.84.72 84.72.41 72.41.9 41.9.61 9.61.73 61.73.95 73.95.65 95.65.13 65.13.58 13.58.96 58.96.98 96.98.1 98.1.21 1.21.74 21.74.65 74.65.35 65.35.5 35.5.73 5.73.11 73.11.51 11.51.87 51.87.41 87.41.12 41.12.8 12.8.20 8.20.31 20.31.31 31.31.15 31.15.95 15.95.22 95.22.73 22.73.79 73.79.88 79.88.34 88.34.8 34.8.11 8.11.49 11.49.34 49.34.90 34.90.59 90.59.96 59.96.60 96.60.55 60.55.75 55.75.77 75.77.44 77.44.2 44.2.7 2.7.85 7.85.57 85.57.74 57.74.29 74.29.70 29.70.59 70.59.19 59.19.39 19.39.26 39.26.26 26.26.47 26.47.80 47.80.90 80.90.36 90.36.58 36.58.47 58.47.9 47.9.72 9.72.72 72.72.66 72.66.33 66.33.93 33.93.75 93.75.64 75.64.81 64.81.9 81.9.23 9.23.37 23.37.13 37.13.12 13.12.14 12.14.62 14.62.91 62.91.36 91.36.91 36.91.33 91.33.15 33.15.34 15.34.36 34.36.99 36.99.3 99.3.95 3.95.69 95.69.58 69.58.52 58.52.30 52.30.50 30.50.84 50.84.10 84.10.84 10.84.33 84.33.21 33.21.39 21.39.44 39.44.58 44.58.30 58.30.38 30.38.34 38.34.83 34.83.27 83.27.82 27.82.17 82.17.7 17.7.5 7.5 5 {} {}} + +do_execsql_test 1.13.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {40.30.80 30.80.20 80.20.90 20.90.60 90.60.70 60.70.80 70.80.90 80.90.30 90.30.50 30.50.10 50.10.30 10.30 30 {} {} 91.61.91 61.91.91 91.91.1 91.1.81 1.81.41 81.41.61 41.61.1 61.1.21 1.21.11 21.11.51 11.51.41 51.41.31 41.31.31 31.31.11 31.11.81 11.81.91 81.91.91 91.91.21 91.21 21 {} {} 12.32.22 32.22.42 22.42.2 42.2.72 2.72.12 72.12.22 12.22.2 22.2.72 2.72.72 72.72.12 72.12.62 12.62.52 62.52.82 52.82 82 {} {} 93.23.93 23.93.43 93.43.3 43.3.43 3.43.33 43.33.53 33.53.63 53.63.73 63.73.13 73.13.73 13.73.73 73.73.33 73.33.93 33.93.23 93.23.13 23.13.33 13.33.3 33.3.33 3.33.83 33.83 83 {} {} 54.84.74 84.74.24 74.24.4 24.4.94 4.94.84 94.84.74 84.74.34 74.34.34 34.34.44 34.44.74 44.74.64 74.64.14 64.14.34 14.34.84 34.84.84 84.84.44 84.44.34 44.34 34 {} {} 85.85.55 85.55.15 55.15.25 15.25.75 25.75.95 75.95.65 95.65.65 65.65.35 65.35.5 35.5.15 5.15.95 15.95.55 95.55.75 55.75.85 75.85.75 85.75.15 75.15.95 15.95.5 95.5 5 {} {} 46.6.46 6.46.16 46.16.16 16.16.86 16.86.56 86.56.56 56.56.56 56.56.16 56.16.36 16.36.76 36.76.96 76.96.96 96.96.26 96.26.26 26.26.36 26.36.66 36.66.36 66.36.36 36.36 36 {} {} 97.67.77 67.77.47 77.47.7 47.7.47 7.47.87 47.87.37 87.37.87 37.87.77 87.77.7 77.7.57 7.57.47 57.47.47 47.47.37 47.37.27 37.27.17 27.17.7 17.7 7 {} {} 78.8.28 8.28.98 28.98.78 98.78.58 78.58.98 58.98.8 98.8.88 8.88.8 88.8.58 8.58.58 58.58.58 58.58.38 58.38 38 {} {} 59.39.99 39.99.29 99.29.59 29.59.89 59.89.89 89.89.29 89.29.9 29.9.79 9.79.49 79.49.59 49.59.29 59.29.59 29.59.19 59.19.39 19.39.9 39.9.9 9.9.99 9.99.69 99.69.39 69.39 39 {} {}} + +do_execsql_test 1.13.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {1.2.2 2.2.2 2.2.3 2.3.3 3.3.4 3.4.5 4.5.5 5.5.6 5.6.7 6.7.7 7.7.7 7.7.8 7.8.8 8.8.8 8.8.9 8.9.9 9.9.9 9.9.10 9.10.11 10.11.11 11.11.12 11.12.12 12.12.12 12.12.13 12.13.13 13.13.14 13.14.15 14.15.15 15.15.15 15.15.16 15.16.16 16.16.16 16.16.17 16.17.19 17.19.20 19.20.21 20.21.21 21.21.22 21.22.22 22.22.23 22.23.23 23.23.23 23.23.24 23.24.25 24.25.26 25.26.26 26.26.26 26.26.27 26.27.27 27.27.28 27.28.29 28.29.29 29.29.29 29.29.30 29.30.30 30.30.30 30.30.31 30.31.31 31.31.32 31.32.33 32.33.33 33.33.33 33.33.33 33.33.33 33.33.34 33.34.34 34.34.34 34.34.34 34.34.35 34.35.35 35.35.36 35.36.36 36.36.36 36.36.36 36.36.37 36.37.37 37.37.38 37.38.38 38.38.39 38.39.39 39.39.39 39.39.40 39.40.41 40.41.41 41.41.41 41.41.42 41.42.43 42.43.43 43.43.44 43.44.44 44.44.46 44.46.46 46.46.47 46.47.47 47.47.47 47.47.47 47.47.49 47.49.50 49.50.51 50.51.52 51.52.53 52.53.54 53.54.55 54.55.55 55.55.56 55.56.56 56.56.56 56.56.57 56.57.58 57.58.58 58.58.58 58.58.58 58.58.59 58.59.59 59.59.59 59.59.59 59.59.60 59.60.61 60.61.61 61.61.62 61.62.62 62.62.63 62.63.64 63.64.65 64.65.65 65.65.65 65.65.66 65.66.67 66.67.68 67.68.69 68.69.70 69.70.72 70.72.72 72.72.72 72.72.73 72.73.73 73.73.73 73.73.74 73.74.74 74.74.74 74.74.74 74.74.74 74.74.75 74.75.75 75.75.75 75.75.76 75.76.77 76.77.77 77.77.78 77.78.78 78.78.79 78.79.80 79.80.80 80.80.81 80.81.81 81.81.81 81.81.82 81.82.83 82.83.84 83.84.84 84.84.84 84.84.84 84.84.85 84.85.85 85.85.85 85.85.86 85.86.87 86.87.87 87.87.88 87.88.89 88.89.89 89.89.89 89.89.90 89.90.90 90.90.90 90.90.91 90.91.91 91.91.91 91.91.91 91.91.91 91.91.93 91.93.93 93.93.93 93.93.94 93.94.95 94.95.95 95.95.95 95.95.96 95.96.96 96.96.96 96.96.97 96.97.97 97.97.98 97.98.98 98.98.99 98.99.99 99.99.99 99.99 99 {} {}} + +do_execsql_test 1.13.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {20.30.30 30.30.30 30.30.40 30.40.50 40.50.60 50.60.70 60.70.80 70.80.80 80.80.90 80.90.90 90.90.90 90.90 90 {} {} 11.11.21 11.21.21 21.21.31 21.31.31 31.31.41 31.41.41 41.41.41 41.41.51 41.51.61 51.61.61 61.61.81 61.81.81 81.81.81 81.81.91 81.91.91 91.91.91 91.91.91 91.91.91 91.91 91 {} {} 2.12.12 12.12.12 12.12.22 12.22.22 22.22.32 22.32.42 32.42.52 42.52.62 52.62.62 62.62.72 62.72.72 72.72.72 72.72.82 72.82 82 {} {} 13.13.23 13.23.23 23.23.23 23.23.33 23.33.33 33.33.33 33.33.33 33.33.33 33.33.43 33.43.43 43.43.53 43.53.63 53.63.73 63.73.73 73.73.73 73.73.83 73.83.93 83.93.93 93.93.93 93.93 93 {} {} 24.34.34 34.34.34 34.34.34 34.34.44 34.44.44 44.44.54 44.54.64 54.64.74 64.74.74 74.74.74 74.74.74 74.74.74 74.74.84 74.84.84 84.84.84 84.84.84 84.84.94 84.94 94 {} {} 15.15.15 15.15.25 15.25.35 25.35.35 35.35.55 35.55.55 55.55.65 55.65.65 65.65.65 65.65.75 65.75.75 75.75.75 75.75.85 75.85.85 85.85.85 85.85.95 85.95.95 95.95.95 95.95 95 {} {} 16.16.26 16.26.26 26.26.26 26.26.36 26.36.36 36.36.36 36.36.36 36.36.46 36.46.46 46.46.56 46.56.56 56.56.56 56.56.66 56.66.76 66.76.86 76.86.96 86.96.96 96.96.96 96.96 96 {} {} 7.17.27 17.27.27 27.27.37 27.37.37 37.37.47 37.47.47 47.47.47 47.47.47 47.47.57 47.57.67 57.67.77 67.77.77 77.77.87 77.87.87 87.87.97 87.97.97 97.97 97 {} {} 8.28.38 28.38.38 38.38.58 38.58.58 58.58.58 58.58.58 58.58.68 58.68.78 68.78.78 78.78.88 78.88.98 88.98.98 98.98 98 {} {} 9.19.29 19.29.29 29.29.29 29.29.39 29.39.39 39.39.39 39.39.49 39.49.59 49.59.59 59.59.59 59.59.59 59.59.69 59.69.79 69.79.89 79.89.89 89.89.89 89.89.99 89.99.99 99.99.99 99.99 99 {} {}} + +do_execsql_test 1.13.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING ) FROM t2 +} {40.30.80 30.80.20 80.20.90 20.90.60 90.60.70 60.70.80 70.80.90 80.90.30 90.30.50 30.50.10 50.10.30 10.30.41 30.41.81 41.81.91 81.91.61 91.61.91 61.91.91 91.91.1 91.1.81 1.81.41 81.41.61 41.61.1 61.1.21 1.21.11 21.11.51 11.51.41 51.41.31 41.31.31 31.31.11 31.11.81 11.81.91 81.91.91 91.91.21 91.21.2 21.2.62 2.62.12 62.12.32 12.32.22 32.22.42 22.42.2 42.2.72 2.72.12 72.12.22 12.22.2 22.2.72 2.72.72 72.72.12 72.12.62 12.62.52 62.52.82 52.82.23 82.23.33 23.33.93 33.93.23 93.23.93 23.93.43 93.43.3 43.3.43 3.43.33 43.33.53 33.53.63 53.63.73 63.73.13 73.13.73 13.73.73 73.73.33 73.33.93 33.93.23 93.23.13 23.13.33 13.33.3 33.3.33 3.33.83 33.83.74 83.74.74 74.74.54 74.54.84 54.84.74 84.74.24 74.24.4 24.4.94 4.94.84 94.84.74 84.74.34 74.34.34 34.34.44 34.44.74 44.74.64 74.64.14 64.14.34 14.34.84 34.84.84 84.84.44 84.44.34 44.34.65 34.65.35 65.35.85 35.85.85 85.85.55 85.55.15 55.15.25 15.25.75 25.75.95 75.95.65 95.65.65 65.65.35 65.35.5 35.5.15 5.15.95 15.95.55 95.55.75 55.75.85 75.85.75 85.75.15 75.15.95 15.95.5 95.5.26 5.26.96 26.96.46 96.46.6 46.6.46 6.46.16 46.16.16 16.16.86 16.86.56 86.56.56 56.56.56 56.56.16 56.16.36 16.36.76 36.76.96 76.96.96 96.96.26 96.26.26 26.26.36 26.36.66 36.66.36 66.36.36 36.36.97 36.97.27 97.27.97 27.97.67 97.67.77 67.77.47 77.47.7 47.7.47 7.47.87 47.87.37 87.37.87 37.87.77 87.77.7 77.7.57 7.57.47 57.47.47 47.47.37 47.37.27 37.27.17 27.17.7 17.7.38 7.38.68 38.68.78 68.78.8 78.8.28 8.28.98 28.98.78 98.78.58 78.58.98 58.98.8 98.8.88 8.88.8 88.8.58 8.58.58 58.58.58 58.58.38 58.38.99 38.99.89 99.89.59 89.59.39 59.39.99 39.99.29 99.29.59 29.59.89 59.89.89 89.89.29 89.29.9 29.9.79 9.79.49 79.49.59 49.59.29 59.29.59 29.59.19 59.19.39 19.39.9 39.9.9 9.9.99 9.99.69 99.69.39 69.39 39 {} {}} + +do_execsql_test 1.13.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.13.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) +} {3 74 3 74.99 3 99 3 99.33 3 33 3 33.89 3 89 3 89.96 3 96 3 96.38 3 38 3 38.39 3 39 3 39.91 3 91 3 91.6 3 6 3 6.97 3 97 3 97.46 3 46 3 46.54 3 54 3 54.8 3 8 3 8.29 3 29 3 29.84 3 84 3 84.23 3 23 3 23.16 3 16 3 16.65 3 65 3 65.47 3 47 3 47.86 3 86 3 86.61 3 61 3 61.85 3 85 3 85.85 3 85 3 85.59 3 59 3 59.32 3 32 3 32.3 3 3 3 3.22 3 22 3 22.55 3 55 3 55.28 3 28 3 28.25 3 25 3 25.1 3 1 3 1.40 3 40 3 40.56 3 56 3 56.75 3 75 3 75.89 3 89 3 89.76 3 76 3 76.4 3 4 3 4.42 3 42 3 42.78 3 78 3 78.29 3 29 3 29.63 3 63 3 63.87 3 87 3 87.80 3 80 3 80.72 3 72 3 72.9 3 9 3 9.73 3 73 3 73.65 3 65 3 65.58 3 58 3 58.98 3 98 3 98.21 3 21 3 21.65 3 65 3 65.5 3 5 3 5.11 3 11 3 11.87 3 87 3 87.12 3 12 3 12.20 3 20 3 20.31 3 31 3 31.95 3 95 3 95.73 3 73 3 73.88 3 88 3 88.8 3 8 3 8.49 3 49 3 49.90 3 90 3 90.96 3 96 3 96.55 3 55 3 55.77 3 77 3 77.2 3 2 3 2.85 3 85 3 85.74 3 74 3 74.70 3 70 3 70.19 3 19 3 19.26 3 26 3 26.47 3 47 3 47.90 3 90 3 90.58 3 58 3 58.9 3 9 3 9.72 3 72 3 72.33 3 33 3 33.75 3 75 3 75.81 3 81 3 81.23 3 23 3 23.13 3 13 3 13.14 3 14 3 14.91 3 91 3 91.91 3 91 3 91.15 3 15 3 15.36 3 36 3 36.3 3 3 3 3.69 3 69 3 69.52 3 52 3 52.50 3 50 3 50.10 3 10 3 10.33 3 33 3 33.39 3 39 3 39.58 3 58 3 58.38 3 38 3 38.83 3 83 3 83.82 3 82 3 82.7 3 7 2 7 1 {} 0 {} 0 {}} + +do_execsql_test 1.13.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) +} {3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {}} + +do_execsql_test 1.13.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) +} {3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {}} + +do_execsql_test 1.13.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) +} {3 29.47.59 3 47.59.28 3 59.28.75 3 28.75.78 3 75.78.72 3 78.72.98 3 72.98.87 3 98.87.73 3 87.73.96 3 73.96.74 3 96.74.90 3 74.90.75 3 90.75.91 3 75.91.69 3 91.69.39 3 69.39.7 2 39.7 1 7 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 97.84.86 3 84.86.32 3 86.32.25 3 32.25.89 3 25.89.29 3 89.29.9 3 29.9.21 3 9.21.12 3 21.12.88 3 12.88.55 3 88.55.70 3 55.70.58 3 70.58.81 3 58.81.91 3 81.91.52 3 91.52.58 2 52.58 1 58 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 46.23.61 3 23.61.3 3 61.3.1 3 3.1.76 3 1.76.63 3 76.63.73 3 63.73.65 3 73.65.20 3 65.20.8 3 20.8.77 3 8.77.19 3 77.19.9 3 19.9.23 3 9.23.15 3 23.15.50 3 15.50.38 2 50.38 1 38 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 54.16.85 3 16.85.22 3 85.22.40 3 22.40.4 3 40.4.87 3 4.87.65 3 87.65.5 3 65.5.31 3 5.31.49 3 31.49.2 3 49.2.26 3 2.26.72 3 26.72.13 3 72.13.36 3 13.36.10 3 36.10.83 2 10.83 1 83 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {} 3 8.65.85 3 65.85.55 3 85.55.56 3 55.56.42 3 56.42.80 3 42.80.58 3 80.58.11 3 58.11.95 3 11.95.90 3 95.90.85 3 90.85.47 3 85.47.33 3 47.33.14 3 33.14.3 3 14.3.33 3 3.33.82 2 33.82 1 82 0 {} 0 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 3 {} 2 {} 1 {} 0 {} 0 {}} + +do_execsql_test 1.14.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.14.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.14.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.14.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.14.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.14.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.14.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.14.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.14.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.14.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.14.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.14.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.14.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.14.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.14.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.14.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.14.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.14.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.14.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.14.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.14.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206} + +do_execsql_test 1.14.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.14.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.14.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.14.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.14.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.14.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 81 86 81 46 98 97 23 41 72 29 13 28 35 16 47 47 9 24 26 98 58 8 24 30 91 58 2 56 29 73 2 42 46 62 62 73 40 16 85 33 37 81 25 9 87 78 87 61 28 59 77 90 74 9 27 41 22 39 67 72 54 85 74 90 7 61 90 62 4 93 72 96 94 29 23 95 74 93 30 23 29 3 1 41 80 65 33 2 98 86 89 25 76 65 40 38 15 13 96 74 97 81 40 16 99 76 96 32 80 86 59 2 99 84 84 39 65 27 76 78 84 16 2 96 59 16 41 28 13 89 22 4 42 91 41 33 87 55 81 29 36 28 6 47 97 97 85 33 41 93 15 85 89 98 98 43 23 73 4 56 29 89 46 65 38 59 68 47 9 93 9 23 39 16 93 98 74 65 75 15 56 93 12 2 81 2 23 97 47 91 15 93 35 16 63 8 53 91 33 99} + +do_execsql_test 1.14.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 90 {} {} {} {} {} {} {} 81 {} {} {} 81 21 21 {} {} {} {} 21 {} {} {} 21 12 {} 72 {} {} {} 12 {} 72 {} 12 {} {} 72 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} 73 {} {} {} {} {} 73 {} 23 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} 55 {} {} {} {} {} {} 15 55 {} {} {} {} {} 55 {} 15 {} {} {} 16 {} 26 26 {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 47 {} {} {} {} {} 27 47 {} {} {} 98 {} {} {} {} {} 98 {} 98 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 29 {} {} {} {} {} 9 {} 29 29 {} {} {}} + +do_execsql_test 1.14.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 4 4 4 5 5 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 8 9 9 10 10 11 11 11 11 11 12 12 12 12 12 13 13 13 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 25 25 25 25 26 26 27 27 28 29 29 29 29 29 29 30 30 30 30 30 30 30 30 30 31 31 31 32 32 33 33 33 33 33 33 33 34 34 34 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 36 37 37 37 38 38 38 38 38 39 39 39 39 39 39 40 40 40 41 41 41 41 42 42 42 43 43 43 43 43 43 43 43 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 47 47} + +do_execsql_test 1.14.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 1 51 51 91 91 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 2 2 62 62 62 {} {} {} {} {} {} {} {} {} {} {} 13 13 43 43 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 25 75 75 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 66 66 66 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 37 37 87 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 58 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 39 39 89 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 74 32 31 84 91 74 3 93 84 74 31 12 90 31 22 74 64 43 64 64 90 74 22 43 90 1 30 62 22 31 31 30 74 64 64 1 40 33 50 11 81 42 40 13 50 81 40 13 13 50 33 52 24 41 81 34 41 34 2 30 2 81 82 53 33 10 33 33 81 34 41 10 81 30 81 4 3 3 23 94 3 61 80 84 94 3 91 91 72 3 63 30 91 94 94 72 91 73 91 84 84 33 41 1 33 84 73 73 91 20 41 84 33 33 84 33 41 84 20 21 44 22 90 22 81 81 74 93 93 93 81 21 83 44 44 21 21 21 13 21 21 34 11 34 73 74 2 60 2 34 2 34 74 60 23 2 2 2 11 91 60 62 73 74 70 51 65 74 93 65 70 34 70 93 93 93 62 35 44 43 12 35 41 43 44 44 41 80 54 72 43 41 43 91 12 80 80 35 33 12} + +do_execsql_test 1.14.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.14.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 74 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99} + +do_execsql_test 1.14.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.14.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9} + +do_execsql_test 1.14.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} + +do_execsql_test 1.14.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.14.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.14.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.14.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.14.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.14.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.14.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5} + +do_execsql_test 1.14.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.14.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99} + +do_execsql_test 1.14.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99} + +do_execsql_test 1.14.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} + +do_execsql_test 1.14.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.14.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7} + +do_execsql_test 1.14.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {} 201 {}} + +do_execsql_test 1.14.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {}} + +do_execsql_test 1.14.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +} {20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 21 {} 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {} 20 {}} + +do_execsql_test 1.15.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 95 95 84 84 84 84 84 84 84 84 83 83 83 83 83 83 83 83 83 82} + +do_execsql_test 1.15.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.15.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.15.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.15.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.15.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.15.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.15.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.15.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.15.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.15.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.15.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.15.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.15.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.15.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.15.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.15.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.15.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.15.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.15.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.15.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206} + +do_execsql_test 1.15.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.15.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.15.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.15.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.15.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.15.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 81 86 81 46 1 67 93 26 95 80 65 56 85 30 12 81 35 89 97 31 31 85 40 96 4 73 84 9 91 73 12 5 56 24 85 49 96 75 53 61 8 8 1 55 34 43 59 80 35 15 78 35 56 70 76 59 51 75 63 26 53 5 89 15 21 5 73 33 29 74 66 12 26 58 4 12 31 35 9 87 73 55 59 53 62 73 23 62 33 90 13 90 9 10 66 5 58 44 38 58 22 33 37 2 73 36 31 72 30 47 73 15 96 70 59 90 {} 7 21 83 {} 47 90 55 36 66 {} 50 {} 84 30 {} {} 34 77 74 {} 58 {} 13 {} 82 93 69 14 62 44 {} {} 30 {} 83 93 {} {} {} 84 {} {} {} {} 14 30 82 34 34 3 {} {} {} {} {} 84 {} {} {} 99 {} {} {} {} {} {} {} 58 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 61 {} {} {} 81 {} 91 {} {} {} {} {} {} {} {} {} 12 {} 72 {} {} {} 22 {} 82 {} 12 {} {} {} {} {} {} {} {} {} {} {} {} 43 {} {} {} {} {} 33 {} {} {} {} {} {} {} 33 {} {} {} {} {} {} {} {} 4 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 15 {} {} {} {} {} {} {} {} {} {} {} {} 16 {} 26 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 {} {} {} {} {} 47 {} {} {} {} {} {} {} {} {} {} 98 {} {} {} {} {} 58 {} 38 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 59 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 1 1 1 2 2 3 4 5 6 7 8 8 8 9 9 10 11 12 12 13 14 15 15 16 16 17 19 21 22 22 23 23 24 25 26 27 29 29 30 30 31 32 33 33 33 34 34 34 35 36 36 36 37 38 38 39 39 40 41 41 43 44 44 46 46 47 47 47 49 50 52 53 55 55 56 56 57 58 58 58 59 59 59 61 62 62 63 65 65 66 68 69 72 72 73 73 74 74 74 75 76 77 78 80 81 81 82 83 84 84 85 85 85 86 87 88 89 89 90 90 91 91 91 93 93 95 95 95 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 1 51 51 91 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 2 2 62 62 72 {} {} {} {} {} {} {} {} {} {} {} 13 13 43 43 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 25 75 75 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 66 66 66 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 37 37 87 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 58 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 39 39 89 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 74 32 31 84 1 14 53 3 84 44 2 93 91 32 52 34 25 33 95 65 61 35 3 74 81 2 91 33 13 23 93 12 5 96 46 82 91 44 2 73 43 84 22 95 82 63 12 75 15 93 35 85 16 33 94 67 83 47 65 43 85 64 95 6 96 33 26 26 65 27 74 74 55 33 25 57 47 7 56 17 37 55 4 58 8 47 15 95 56 17 37 55 6 58 58 26 86 27 56 39 99 77 75 16 58 9 78 58 36 15 46 {} 78 89 9 29 56 {} 26 97 {} 78 16 28 26 36 {} 59 39 99 27 78 {} {} {} 37 27 98 {} 88 8 {} 28 {} {} {} 49 37 29 {} 59 {} {} 47 {} 69 39 59 99 8 78 9 {} {} 58 49 {} {} {} {} 58 {} 38 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 59 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 0 0 0 0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27} + +do_execsql_test 1.15.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 0 0 0 0 90 40 30 80 20 90 60 70 80 90 41 41 41 41 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 2 2 2 2 2 62 12 32 22 42 2 72 12 22 2 72 72 23 23 23 23 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 74 74 74 74 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 65 65 65 65 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 26 26 26 26 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 97 97 97 97 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 38 38 38 38 38 68 78 8 28 98 78 58 98 8 88 8 99 99 99 99 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.15.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98} + +do_execsql_test 1.15.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 10 20 30 30 30 40 50 60 70 80 1 1 1 1 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 2 2 2 2 2 2 2 12 12 12 22 22 32 42 52 62 62 3 3 3 3 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 4 4 4 4 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 5 5 5 5 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 6 6 6 6 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 7 7 7 7 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 8 8 8 8 8 8 8 28 38 38 58 58 58 58 68 78 9 9 9 9 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89} + +do_execsql_test 1.15.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 0 0 0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9} + +do_execsql_test 1.15.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.15.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.15.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.15.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.15.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.15.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.15.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.39.44.58.30.38.34.83.27.82.17.7.5 39.44.58.30.38.34.83.27.82.17.7.5 44.58.30.38.34.83.27.82.17.7.5 58.30.38.34.83.27.82.17.7.5 30.38.34.83.27.82.17.7.5 38.34.83.27.82.17.7.5 34.83.27.82.17.7.5 83.27.82.17.7.5 27.82.17.7.5} + +do_execsql_test 1.15.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 90.40.30.80.20.90.60.70.80.90.30.50.10.30 40.30.80.20.90.60.70.80.90.30.50.10.30 30.80.20.90.60.70.80.90.30.50.10.30 80.20.90.60.70.80.90.30.50.10.30 20.90.60.70.80.90.30.50.10.30 90.60.70.80.90.30.50.10.30 60.70.80.90.30.50.10.30 70.80.90.30.50.10.30 80.90.30.50.10.30 90.30.50.10.30 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.61.1.21.11.51.41.31.31.11.81.91.91.21 61.1.21.11.51.41.31.31.11.81.91.91.21 1.21.11.51.41.31.31.11.81.91.91.21 21.11.51.41.31.31.11.81.91.91.21 11.51.41.31.31.11.81.91.91.21 51.41.31.31.11.81.91.91.21 41.31.31.11.81.91.91.21 31.31.11.81.91.91.21 31.11.81.91.91.21 11.81.91.91.21 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 32.22.42.2.72.12.22.2.72.72.12.62.52.82 22.42.2.72.12.22.2.72.72.12.62.52.82 42.2.72.12.22.2.72.72.12.62.52.82 2.72.12.22.2.72.72.12.62.52.82 72.12.22.2.72.72.12.62.52.82 12.22.2.72.72.12.62.52.82 22.2.72.72.12.62.52.82 2.72.72.12.62.52.82 72.72.12.62.52.82 72.12.62.52.82 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 53.63.73.13.73.73.33.93.23.13.33.3.33.83 63.73.13.73.73.33.93.23.13.33.3.33.83 73.13.73.73.33.93.23.13.33.3.33.83 13.73.73.33.93.23.13.33.3.33.83 73.73.33.93.23.13.33.3.33.83 73.33.93.23.13.33.3.33.83 33.93.23.13.33.3.33.83 93.23.13.33.3.33.83 23.13.33.3.33.83 13.33.3.33.83 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 94.84.74.34.34.44.74.64.14.34.84.84.44.34 84.74.34.34.44.74.64.14.34.84.84.44.34 74.34.34.44.74.64.14.34.84.84.44.34 34.34.44.74.64.14.34.84.84.44.34 34.44.74.64.14.34.84.84.44.34 44.74.64.14.34.84.84.44.34 74.64.14.34.84.84.44.34 64.14.34.84.84.44.34 14.34.84.84.44.34 34.84.84.44.34 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.5.15.95.55.75.85.75.15.95.5 35.5.15.95.55.75.85.75.15.95.5 5.15.95.55.75.85.75.15.95.5 15.95.55.75.85.75.15.95.5 95.55.75.85.75.15.95.5 55.75.85.75.15.95.5 75.85.75.15.95.5 85.75.15.95.5 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.16.36.76.96.96.26.26.36.66.36.36 56.16.36.76.96.96.26.26.36.66.36.36 16.36.76.96.96.26.26.36.66.36.36 36.76.96.96.26.26.36.66.36.36 76.96.96.26.26.36.66.36.36 96.96.26.26.36.66.36.36 96.26.26.36.66.36.36 26.26.36.66.36.36 26.36.66.36.36 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.87.37.87.77.7.57.47.47.37.27.17.7 87.37.87.77.7.57.47.47.37.27.17.7 37.87.77.7.57.47.47.37.27.17.7 87.77.7.57.47.47.37.27.17.7 77.7.57.47.47.37.27.17.7 7.57.47.47.37.27.17.7 57.47.47.37.27.17.7 47.47.37.27.17.7 47.37.27.17.7 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 78.8.28.98.78.58.98.8.88.8.58.58.58.38 8.28.98.78.58.98.8.88.8.58.58.58.38 28.98.78.58.98.8.88.8.58.58.58.38 98.78.58.98.8.88.8.58.58.58.38 78.58.98.8.88.8.58.58.58.38 58.98.8.88.8.58.58.58.38 98.8.88.8.58.58.58.38 8.88.8.58.58.58.38 88.8.58.58.58.38 8.58.58.58.38 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39} + +do_execsql_test 1.15.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 94.95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.96.96.96.97.97.98.98.99.99.99 95.96.96.96.97.97.98.98.99.99.99 96.96.96.97.97.98.98.99.99.99 96.96.97.97.98.98.99.99.99 96.97.97.98.98.99.99.99 97.97.98.98.99.99.99 97.98.98.99.99.99 98.98.99.99.99} + +do_execsql_test 1.15.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 10.20.30.30.30.40.50.60.70.80.80.90.90.90 20.30.30.30.40.50.60.70.80.80.90.90.90 30.30.30.40.50.60.70.80.80.90.90.90 30.30.40.50.60.70.80.80.90.90.90 30.40.50.60.70.80.80.90.90.90 40.50.60.70.80.80.90.90.90 50.60.70.80.80.90.90.90 60.70.80.80.90.90.90 70.80.80.90.90.90 80.80.90.90.90 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.51.61.61.81.81.81.91.91.91.91.91 41.51.61.61.81.81.81.91.91.91.91.91 51.61.61.81.81.81.91.91.91.91.91 61.61.81.81.81.91.91.91.91.91 61.81.81.81.91.91.91.91.91 81.81.81.91.91.91.91.91 81.81.91.91.91.91.91 81.91.91.91.91.91 91.91.91.91.91 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 12.12.12.22.22.32.42.52.62.62.72.72.72.82 12.12.22.22.32.42.52.62.62.72.72.72.82 12.22.22.32.42.52.62.62.72.72.72.82 22.22.32.42.52.62.62.72.72.72.82 22.32.42.52.62.62.72.72.72.82 32.42.52.62.62.72.72.72.82 42.52.62.62.72.72.72.82 52.62.62.72.72.72.82 62.62.72.72.72.82 62.72.72.72.82 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.43.43.53.63.73.73.73.83.93.93.93 33.43.43.53.63.73.73.73.83.93.93.93 43.43.53.63.73.73.73.83.93.93.93 43.53.63.73.73.73.83.93.93.93 53.63.73.73.73.83.93.93.93 63.73.73.73.83.93.93.93 73.73.73.83.93.93.93 73.73.83.93.93.93 73.83.93.93.93 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.54.64.74.74.74.74.74.84.84.84.84.94 54.64.74.74.74.74.74.84.84.84.84.94 64.74.74.74.74.74.84.84.84.84.94 74.74.74.74.74.84.84.84.84.94 74.74.74.74.84.84.84.84.94 74.74.74.84.84.84.84.94 74.74.84.84.84.84.94 74.84.84.84.84.94 84.84.84.84.94 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.65.65.65.75.75.75.85.85.85.95.95.95 65.65.65.75.75.75.85.85.85.95.95.95 65.65.75.75.75.85.85.85.95.95.95 65.75.75.75.85.85.85.95.95.95 75.75.75.85.85.85.95.95.95 75.75.85.85.85.95.95.95 75.85.85.85.95.95.95 85.85.85.95.95.95 85.85.95.95.95 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.46.46.56.56.56.66.76.86.96.96.96 36.46.46.56.56.56.66.76.86.96.96.96 46.46.56.56.56.66.76.86.96.96.96 46.56.56.56.66.76.86.96.96.96 56.56.56.66.76.86.96.96.96 56.56.66.76.86.96.96.96 56.66.76.86.96.96.96 66.76.86.96.96.96 76.86.96.96.96 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.57.67.77.77.87.87.97.97 47.47.57.67.77.77.87.87.97.97 47.57.67.77.77.87.87.97.97 57.67.77.77.87.87.97.97 67.77.77.87.87.97.97 77.77.87.87.97.97 77.87.87.97.97 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.28.38.38.58.58.58.58.68.78.78.88.98.98 28.38.38.58.58.58.58.68.78.78.88.98.98 38.38.58.58.58.58.68.78.78.88.98.98 38.58.58.58.58.68.78.78.88.98.98 58.58.58.58.68.78.78.88.98.98 58.58.58.68.78.78.88.98.98 58.58.68.78.78.88.98.98 58.68.78.78.88.98.98 68.78.78.88.98.98 78.78.88.98.98 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.49.59.59.59.59.69.79.89.89.89.99.99.99 49.59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.69.79.89.89.89.99.99.99 59.59.69.79.89.89.89.99.99.99 59.69.79.89.89.89.99.99.99 69.79.89.89.89.99.99.99 79.89.89.89.99.99.99 89.89.89.99.99.99 89.89.99.99.99} + +do_execsql_test 1.15.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39} + +do_execsql_test 1.15.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.15.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) +} {201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 200 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 199 74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 198 74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 197 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 196 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 195 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 194 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 193 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 192 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 191 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 190 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 189 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 188 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 187 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 186 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 185 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 184 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 183 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 182 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 181 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 180 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 179 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 178 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 177 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 176 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 175 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 174 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 173 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 172 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 171 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 170 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 169 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 168 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 167 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 166 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 165 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 164 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 163 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 162 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 161 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 160 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 159 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 158 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 157 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 156 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 155 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 154 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 153 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 152 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 151 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 150 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 149 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 148 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 147 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 146 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 145 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 144 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 143 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 142 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 141 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 140 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 139 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 138 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 137 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 136 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 135 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 134 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 133 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 132 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 131 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 130 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 129 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 128 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 127 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 126 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 125 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 124 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 123 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 122 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 121 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 120 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 119 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 118 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 117 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 116 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 115 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 114 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 113 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 112 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 111 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 110 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 109 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 108 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 107 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 106 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 105 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 104 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 103 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 102 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 101 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 100 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 99 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 98 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 97 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 96 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 95 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 94 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 93 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 92 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 91 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 90 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 89 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 88 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 87 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 86 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 85 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 84 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 83 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 82 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 81 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 80 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 79 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 78 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 77 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 76 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 75 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 74 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 73 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 72 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 71 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 70 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 69 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 68 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 67 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 66 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 65 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 64 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 63 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 62 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 61 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 60 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 59 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 58 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 57 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 56 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 55 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 54 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 53 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 52 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 51 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 50 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 49 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 48 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 47 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 46 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 45 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 44 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 43 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 42 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 41 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 40 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 39 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 38 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 37 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 36 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 35 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 34 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 33 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 32 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 31 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 30 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 29 15.36.3.69.52.50.10.33.39.58.38.83.82.7 28 15.36.3.69.52.50.10.33.39.58.38.83.82.7 27 36.3.69.52.50.10.33.39.58.38.83.82.7 26 36.3.69.52.50.10.33.39.58.38.83.82.7 25 3.69.52.50.10.33.39.58.38.83.82.7 24 3.69.52.50.10.33.39.58.38.83.82.7 23 69.52.50.10.33.39.58.38.83.82.7 22 69.52.50.10.33.39.58.38.83.82.7 21 52.50.10.33.39.58.38.83.82.7 20 52.50.10.33.39.58.38.83.82.7 19 50.10.33.39.58.38.83.82.7 18 50.10.33.39.58.38.83.82.7 17 10.33.39.58.38.83.82.7 16 10.33.39.58.38.83.82.7 15 33.39.58.38.83.82.7 14 33.39.58.38.83.82.7 13 39.58.38.83.82.7 12 39.58.38.83.82.7 11 58.38.83.82.7 10 58.38.83.82.7 9 38.83.82.7 8 38.83.82.7 7 83.82.7 6 83.82.7 5 82.7} + +do_execsql_test 1.15.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) +} {201 {} 201 {} 201 {} 201 {} 201 {} 200 {} 199 {} 198 {} 197 {} 196 {} 195 {} 194 {} 193 {} 192 {} 191 {} 190 {} 189 {} 188 {} 187 {} 186 {} 185 {} 184 {} 183 {} 182 {} 181 {} 180 {} 179 {} 178 {} 177 {} 176 {} 175 {} 174 {} 173 {} 172 {} 171 {} 170 {} 169 {} 168 {} 167 {} 166 {} 165 {} 164 {} 163 {} 162 {} 161 {} 160 {} 159 {} 158 {} 157 {} 156 {} 155 {} 154 {} 153 {} 152 {} 151 {} 150 {} 149 {} 148 {} 147 {} 146 {} 145 {} 144 {} 143 {} 142 {} 141 {} 140 {} 139 {} 138 {} 137 {} 136 {} 135 {} 134 {} 133 {} 132 {} 131 {} 130 {} 129 {} 128 {} 127 {} 126 {} 125 {} 124 {} 123 {} 122 {} 121 {} 120 {} 119 {} 118 {} 117 {} 116 {} 115 {} 114 {} 113 {} 112 {} 111 {} 110 {} 109 {} 108 {} 107 {} 106 {} 105 {} 104 {} 103 {} 102 {} 101 {} 100 {} 99 {} 98 {} 97 {} 96 {} 95 {} 94 {} 93 {} 92 {} 91 {} 90 {} 89 {} 88 {} 87 {} 86 {} 85 {} 84 {} 83 {} 82 {} 81 {} 80 {} 79 {} 78 {} 77 {} 76 {} 75 {} 74 {} 73 {} 72 {} 71 {} 70 {} 69 {} 68 {} 67 {} 66 {} 65 {} 64 {} 63 {} 62 {} 61 {} 60 {} 59 {} 58 {} 57 {} 56 {} 55 {} 54 {} 53 {} 52 {} 51 {} 50 {} 49 {} 48 {} 47 {} 46 {} 45 {} 44 {} 43 {} 42 {} 41 {} 40 {} 39 {} 38 {} 37 {} 36 {} 35 {} 34 {} 33 {} 32 {} 31 {} 30 {} 29 {} 28 {} 27 {} 26 {} 25 {} 24 {} 23 {} 22 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {}} + +do_execsql_test 1.15.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) +} {20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 21 {} 21 {} 21 {} 21 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {}} + +do_execsql_test 1.15.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING) +} {20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 19 6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 18 29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 17 47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 16 59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 15 28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 14 75.78.72.98.87.73.96.74.90.75.91.69.39.7 13 78.72.98.87.73.96.74.90.75.91.69.39.7 12 72.98.87.73.96.74.90.75.91.69.39.7 11 98.87.73.96.74.90.75.91.69.39.7 10 87.73.96.74.90.75.91.69.39.7 9 73.96.74.90.75.91.69.39.7 8 96.74.90.75.91.69.39.7 7 74.90.75.91.69.39.7 6 90.75.91.69.39.7 5 75.91.69.39.7 21 {} 21 {} 21 {} 21 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 19 96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 18 97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 17 84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 16 86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 15 32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 14 25.89.29.9.21.12.88.55.70.58.81.91.52.58 13 89.29.9.21.12.88.55.70.58.81.91.52.58 12 29.9.21.12.88.55.70.58.81.91.52.58 11 9.21.12.88.55.70.58.81.91.52.58 10 21.12.88.55.70.58.81.91.52.58 9 12.88.55.70.58.81.91.52.58 8 88.55.70.58.81.91.52.58 7 55.70.58.81.91.52.58 6 70.58.81.91.52.58 5 58.81.91.52.58 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 19 38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 18 46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 17 23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 16 61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 15 3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 14 1.76.63.73.65.20.8.77.19.9.23.15.50.38 13 76.63.73.65.20.8.77.19.9.23.15.50.38 12 63.73.65.20.8.77.19.9.23.15.50.38 11 73.65.20.8.77.19.9.23.15.50.38 10 65.20.8.77.19.9.23.15.50.38 9 20.8.77.19.9.23.15.50.38 8 8.77.19.9.23.15.50.38 7 77.19.9.23.15.50.38 6 19.9.23.15.50.38 5 9.23.15.50.38 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 19 39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 18 54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 17 16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 16 85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 15 22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 14 40.4.87.65.5.31.49.2.26.72.13.36.10.83 13 4.87.65.5.31.49.2.26.72.13.36.10.83 12 87.65.5.31.49.2.26.72.13.36.10.83 11 65.5.31.49.2.26.72.13.36.10.83 10 5.31.49.2.26.72.13.36.10.83 9 31.49.2.26.72.13.36.10.83 8 49.2.26.72.13.36.10.83 7 2.26.72.13.36.10.83 6 26.72.13.36.10.83 5 72.13.36.10.83 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 19 91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 18 8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 17 65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 16 85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 15 55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 14 56.42.80.58.11.95.90.85.47.33.14.3.33.82 13 42.80.58.11.95.90.85.47.33.14.3.33.82 12 80.58.11.95.90.85.47.33.14.3.33.82 11 58.11.95.90.85.47.33.14.3.33.82 10 11.95.90.85.47.33.14.3.33.82 9 95.90.85.47.33.14.3.33.82 8 90.85.47.33.14.3.33.82 7 85.47.33.14.3.33.82 6 47.33.14.3.33.82 5 33.14.3.33.82 20 {} 20 {} 20 {} 20 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {}} + +do_execsql_test 1.16.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 95 95 84 84 84 84 84 84 84 84 83 83 83 83 83 83 83 83 83 82 82 17 7 5} + +do_execsql_test 1.16.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.16.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.16.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.16.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.16.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.16.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.16.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.16.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.16.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.16.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.16.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.16.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.16.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.16.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.16.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.16.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.16.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.16.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.16.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.16.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206} + +do_execsql_test 1.16.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {223 223 223 223 223 223 223 223 223 223 223 223 223 223 223 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 232 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.16.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.16.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 280 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 198 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276} + +do_execsql_test 1.16.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229} + +do_execsql_test 1.16.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {1 76 78 33 11 108 52 83 79 65 26 70 103 80 36 116 51 52 128 117 71 63 84 109 78 147 88 121 106 124 85 107 171 150 80 171 120 109 158 87 168 173 162 156 195 198 177 124 121 134 141 210 157 132 161 218 226 191 179 138 214 212 172 173 229 240 187 210 227 228 223 225 179 182 231 207 209 212 239 234 213 234 269 196 271 235 250 223 232 229 280 44 28 105 41 99 92 72 55 109 120 119 50 124 96 59 124 110 57 130 103 74 87 48 105 136 131 133 92 109 57 146 113 74 150 87 110 65 110 145 161 156 114 111 136 147 173 124 132 101 154 167 190 161 110 102 123 169 140 111 180 119 160 197 152 146 147 132 213 193 200 136 175 188 187 208 211 144 223 196 170 202 163 184 195 200 163 191 252 235 243 172 187 202 179 261 263 206 189 276 181 274 249 221 210 229 279 224 216 207 206} + +do_execsql_test 1.16.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 41 74 23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5} + +do_execsql_test 1.16.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.16.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 1 2 2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99} + +do_execsql_test 1.16.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 10 20 30 30 30 40 50 60 70 80 80 90 90 90 1 1 11 11 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 2 2 2 12 12 12 22 22 32 42 52 62 62 72 72 72 82 3 3 13 13 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 4 14 24 34 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 5 5 15 15 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 6 16 16 16 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 7 7 7 17 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 8 8 8 28 38 38 58 58 58 58 68 78 78 88 98 98 9 9 9 19 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99} + +do_execsql_test 1.16.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 90 40 30 80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39} + +do_execsql_test 1.16.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.16.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.16.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.16.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.16.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.16.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.16.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0.74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.39.44.58.30.38.34.83.27.82.17.7.5 39.44.58.30.38.34.83.27.82.17.7.5 44.58.30.38.34.83.27.82.17.7.5 58.30.38.34.83.27.82.17.7.5 30.38.34.83.27.82.17.7.5 38.34.83.27.82.17.7.5 34.83.27.82.17.7.5 83.27.82.17.7.5 27.82.17.7.5 82.17.7.5 17.7.5 7.5 5} + +do_execsql_test 1.16.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30 90.40.30.80.20.90.60.70.80.90.30.50.10.30 40.30.80.20.90.60.70.80.90.30.50.10.30 30.80.20.90.60.70.80.90.30.50.10.30 80.20.90.60.70.80.90.30.50.10.30 20.90.60.70.80.90.30.50.10.30 90.60.70.80.90.30.50.10.30 60.70.80.90.30.50.10.30 70.80.90.30.50.10.30 80.90.30.50.10.30 90.30.50.10.30 30.50.10.30 50.10.30 10.30 30 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.61.1.21.11.51.41.31.31.11.81.91.91.21 61.1.21.11.51.41.31.31.11.81.91.91.21 1.21.11.51.41.31.31.11.81.91.91.21 21.11.51.41.31.31.11.81.91.91.21 11.51.41.31.31.11.81.91.91.21 51.41.31.31.11.81.91.91.21 41.31.31.11.81.91.91.21 31.31.11.81.91.91.21 31.11.81.91.91.21 11.81.91.91.21 81.91.91.21 91.91.21 91.21 21 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 12.32.22.42.2.72.12.22.2.72.72.12.62.52.82 32.22.42.2.72.12.22.2.72.72.12.62.52.82 22.42.2.72.12.22.2.72.72.12.62.52.82 42.2.72.12.22.2.72.72.12.62.52.82 2.72.12.22.2.72.72.12.62.52.82 72.12.22.2.72.72.12.62.52.82 12.22.2.72.72.12.62.52.82 22.2.72.72.12.62.52.82 2.72.72.12.62.52.82 72.72.12.62.52.82 72.12.62.52.82 12.62.52.82 62.52.82 52.82 82 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 53.63.73.13.73.73.33.93.23.13.33.3.33.83 63.73.13.73.73.33.93.23.13.33.3.33.83 73.13.73.73.33.93.23.13.33.3.33.83 13.73.73.33.93.23.13.33.3.33.83 73.73.33.93.23.13.33.3.33.83 73.33.93.23.13.33.3.33.83 33.93.23.13.33.3.33.83 93.23.13.33.3.33.83 23.13.33.3.33.83 13.33.3.33.83 33.3.33.83 3.33.83 33.83 83 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 94.84.74.34.34.44.74.64.14.34.84.84.44.34 84.74.34.34.44.74.64.14.34.84.84.44.34 74.34.34.44.74.64.14.34.84.84.44.34 34.34.44.74.64.14.34.84.84.44.34 34.44.74.64.14.34.84.84.44.34 44.74.64.14.34.84.84.44.34 74.64.14.34.84.84.44.34 64.14.34.84.84.44.34 14.34.84.84.44.34 34.84.84.44.34 84.84.44.34 84.44.34 44.34 34 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.5.15.95.55.75.85.75.15.95.5 35.5.15.95.55.75.85.75.15.95.5 5.15.95.55.75.85.75.15.95.5 15.95.55.75.85.75.15.95.5 95.55.75.85.75.15.95.5 55.75.85.75.15.95.5 75.85.75.15.95.5 85.75.15.95.5 75.15.95.5 15.95.5 95.5 5 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.16.36.76.96.96.26.26.36.66.36.36 56.16.36.76.96.96.26.26.36.66.36.36 16.36.76.96.96.26.26.36.66.36.36 36.76.96.96.26.26.36.66.36.36 76.96.96.26.26.36.66.36.36 96.96.26.26.36.66.36.36 96.26.26.36.66.36.36 26.26.36.66.36.36 26.36.66.36.36 36.66.36.36 66.36.36 36.36 36 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.87.37.87.77.7.57.47.47.37.27.17.7 87.37.87.77.7.57.47.47.37.27.17.7 37.87.77.7.57.47.47.37.27.17.7 87.77.7.57.47.47.37.27.17.7 77.7.57.47.47.37.27.17.7 7.57.47.47.37.27.17.7 57.47.47.37.27.17.7 47.47.37.27.17.7 47.37.27.17.7 37.27.17.7 27.17.7 17.7 7 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 68.78.8.28.98.78.58.98.8.88.8.58.58.58.38 78.8.28.98.78.58.98.8.88.8.58.58.58.38 8.28.98.78.58.98.8.88.8.58.58.58.38 28.98.78.58.98.8.88.8.58.58.58.38 98.78.58.98.8.88.8.58.58.58.38 78.58.98.8.88.8.58.58.58.38 58.98.8.88.8.58.58.58.38 98.8.88.8.58.58.58.38 8.88.8.58.58.58.38 88.8.58.58.58.38 8.58.58.58.38 58.58.58.38 58.58.38 58.38 38 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39} + +do_execsql_test 1.16.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 1.1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 1.2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 94.95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.96.96.96.97.97.98.98.99.99.99 95.96.96.96.97.97.98.98.99.99.99 96.96.96.97.97.98.98.99.99.99 96.96.97.97.98.98.99.99.99 96.97.97.98.98.99.99.99 97.97.98.98.99.99.99 97.98.98.99.99.99 98.98.99.99.99 98.99.99.99 99.99.99 99.99 99} + +do_execsql_test 1.16.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.10.20.30.30.30.40.50.60.70.80.80.90.90.90 10.20.30.30.30.40.50.60.70.80.80.90.90.90 20.30.30.30.40.50.60.70.80.80.90.90.90 30.30.30.40.50.60.70.80.80.90.90.90 30.30.40.50.60.70.80.80.90.90.90 30.40.50.60.70.80.80.90.90.90 40.50.60.70.80.80.90.90.90 50.60.70.80.80.90.90.90 60.70.80.80.90.90.90 70.80.80.90.90.90 80.80.90.90.90 80.90.90.90 90.90.90 90.90 90 1.1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 1.11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 11.11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 11.21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.51.61.61.81.81.81.91.91.91.91.91 41.51.61.61.81.81.81.91.91.91.91.91 51.61.61.81.81.81.91.91.91.91.91 61.61.81.81.81.91.91.91.91.91 61.81.81.81.91.91.91.91.91 81.81.81.91.91.91.91.91 81.81.91.91.91.91.91 81.91.91.91.91.91 91.91.91.91.91 91.91.91.91 91.91.91 91.91 91 2.2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 2.12.12.12.22.22.32.42.52.62.62.72.72.72.82 12.12.12.22.22.32.42.52.62.62.72.72.72.82 12.12.22.22.32.42.52.62.62.72.72.72.82 12.22.22.32.42.52.62.62.72.72.72.82 22.22.32.42.52.62.62.72.72.72.82 22.32.42.52.62.62.72.72.72.82 32.42.52.62.62.72.72.72.82 42.52.62.62.72.72.72.82 52.62.62.72.72.72.82 62.62.72.72.72.82 62.72.72.72.82 72.72.72.82 72.72.82 72.82 82 3.3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 3.13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 13.13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 13.23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.43.43.53.63.73.73.73.83.93.93.93 33.43.43.53.63.73.73.73.83.93.93.93 43.43.53.63.73.73.73.83.93.93.93 43.53.63.73.73.73.83.93.93.93 53.63.73.73.73.83.93.93.93 63.73.73.73.83.93.93.93 73.73.73.83.93.93.93 73.73.83.93.93.93 73.83.93.93.93 83.93.93.93 93.93.93 93.93 93 4.14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 14.24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 24.34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.54.64.74.74.74.74.74.84.84.84.84.94 54.64.74.74.74.74.74.84.84.84.84.94 64.74.74.74.74.74.84.84.84.84.94 74.74.74.74.74.84.84.84.84.94 74.74.74.74.84.84.84.84.94 74.74.74.84.84.84.84.94 74.74.84.84.84.84.94 74.84.84.84.84.94 84.84.84.84.94 84.84.84.94 84.84.94 84.94 94 5.5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 5.15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.65.65.65.75.75.75.85.85.85.95.95.95 65.65.65.75.75.75.85.85.85.95.95.95 65.65.75.75.75.85.85.85.95.95.95 65.75.75.75.85.85.85.95.95.95 75.75.75.85.85.85.95.95.95 75.75.85.85.85.95.95.95 75.85.85.85.95.95.95 85.85.85.95.95.95 85.85.95.95.95 85.95.95.95 95.95.95 95.95 95 6.16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 16.26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.46.46.56.56.56.66.76.86.96.96.96 36.46.46.56.56.56.66.76.86.96.96.96 46.46.56.56.56.66.76.86.96.96.96 46.56.56.56.66.76.86.96.96.96 56.56.56.66.76.86.96.96.96 56.56.66.76.86.96.96.96 56.66.76.86.96.96.96 66.76.86.96.96.96 76.86.96.96.96 86.96.96.96 96.96.96 96.96 96 7.7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 7.17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 17.27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.57.67.77.77.87.87.97.97 47.47.57.67.77.77.87.87.97.97 47.57.67.77.77.87.87.97.97 57.67.77.77.87.87.97.97 67.77.77.87.87.97.97 77.77.87.87.97.97 77.87.87.97.97 87.87.97.97 87.97.97 97.97 97 8.8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.8.28.38.38.58.58.58.58.68.78.78.88.98.98 8.28.38.38.58.58.58.58.68.78.78.88.98.98 28.38.38.58.58.58.58.68.78.78.88.98.98 38.38.58.58.58.58.68.78.78.88.98.98 38.58.58.58.58.68.78.78.88.98.98 58.58.58.58.68.78.78.88.98.98 58.58.58.68.78.78.88.98.98 58.58.68.78.78.88.98.98 58.68.78.78.88.98.98 68.78.78.88.98.98 78.78.88.98.98 78.88.98.98 88.98.98 98.98 98 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.49.59.59.59.59.69.79.89.89.89.99.99.99 49.59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.69.79.89.89.89.99.99.99 59.59.69.79.89.89.89.99.99.99 59.69.79.89.89.89.99.99.99 69.79.89.89.89.99.99.99 79.89.89.89.99.99.99 89.89.89.99.99.99 89.89.99.99.99 89.99.99.99 99.99.99 99.99 99} + +do_execsql_test 1.16.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 +} {0.90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 40.30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39} + +do_execsql_test 1.16.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t2 +} {0 74 74 26 2 96 38 68 62 46 6 46 78 54 8 84 16 16 86 74 24 12 32 56 22 90 28 56 40 56 16 36 98 76 4 94 42 30 78 2 80 84 72 58 96 98 74 12 8 20 22 88 34 8 34 90 96 60 44 2 74 70 26 26 80 90 36 58 72 72 66 64 12 14 62 36 34 36 58 52 30 50 84 10 84 44 58 30 38 34 82 41 23 99 33 89 81 59 39 91 99 97 27 97 67 29 93 77 23 93 65 35 47 7 61 91 85 85 43 59 3 91 55 15 89 25 47 1 43 75 89 81 33 29 53 63 87 37 41 9 61 73 95 65 13 1 21 65 35 5 73 11 51 87 41 31 31 15 95 73 79 11 49 59 55 75 77 7 85 57 29 59 19 39 47 47 9 33 93 75 81 9 23 37 13 91 91 33 15 99 3 95 69 33 21 39 83 27 17 7 5} + +do_execsql_test 1.16.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {201 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 200 74.74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 199 74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 198 74.99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 197 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 196 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 195 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 194 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 193 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 192 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 191 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 190 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 189 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 188 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 187 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 186 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 185 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 184 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 183 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 182 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 181 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 180 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 179 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 178 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 177 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 176 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 175 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 174 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 173 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 172 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 171 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 170 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 169 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 168 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 167 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 166 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 165 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 164 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 163 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 162 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 161 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 160 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 159 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 158 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 157 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 156 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 155 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 154 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 153 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 152 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 151 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 150 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 149 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 148 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 147 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 146 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 145 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 144 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 143 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 142 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 141 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 140 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 139 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 138 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 137 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 136 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 135 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 134 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 133 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 132 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 131 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 130 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 129 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 128 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 127 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 126 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 125 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 124 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 123 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 122 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 121 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 120 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 119 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 118 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 117 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 116 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 115 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 114 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 113 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 112 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 111 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 110 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 109 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 108 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 107 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 106 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 105 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 104 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 103 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 102 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 101 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 100 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 99 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 98 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 97 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 96 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 95 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 94 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 93 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 92 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 91 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 90 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 89 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 88 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 87 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 86 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 85 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 84 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 83 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 82 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 81 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 80 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 79 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 78 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 77 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 76 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 75 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 74 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 73 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 72 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 71 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 70 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 69 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 68 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 67 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 66 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 65 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 64 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 63 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 62 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 61 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 60 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 59 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 58 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 57 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 56 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 55 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 54 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 53 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 52 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 51 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 50 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 49 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 48 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 47 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 46 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 45 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 44 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 43 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 42 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 41 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 40 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 39 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 38 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 37 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 36 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 35 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 34 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 33 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 32 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 31 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 30 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 29 15.36.3.69.52.50.10.33.39.58.38.83.82.7 28 15.36.3.69.52.50.10.33.39.58.38.83.82.7 27 36.3.69.52.50.10.33.39.58.38.83.82.7 26 36.3.69.52.50.10.33.39.58.38.83.82.7 25 3.69.52.50.10.33.39.58.38.83.82.7 24 3.69.52.50.10.33.39.58.38.83.82.7 23 69.52.50.10.33.39.58.38.83.82.7 22 69.52.50.10.33.39.58.38.83.82.7 21 52.50.10.33.39.58.38.83.82.7 20 52.50.10.33.39.58.38.83.82.7 19 50.10.33.39.58.38.83.82.7 18 50.10.33.39.58.38.83.82.7 17 10.33.39.58.38.83.82.7 16 10.33.39.58.38.83.82.7 15 33.39.58.38.83.82.7 14 33.39.58.38.83.82.7 13 39.58.38.83.82.7 12 39.58.38.83.82.7 11 58.38.83.82.7 10 58.38.83.82.7 9 38.83.82.7 8 38.83.82.7 7 83.82.7 6 83.82.7 5 82.7 4 82.7 3 7 2 7 1 {}} + +do_execsql_test 1.16.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {201 {} 200 {} 199 {} 198 {} 197 {} 196 {} 195 {} 194 {} 193 {} 192 {} 191 {} 190 {} 189 {} 188 {} 187 {} 186 {} 185 {} 184 {} 183 {} 182 {} 181 {} 180 {} 179 {} 178 {} 177 {} 176 {} 175 {} 174 {} 173 {} 172 {} 171 {} 170 {} 169 {} 168 {} 167 {} 166 {} 165 {} 164 {} 163 {} 162 {} 161 {} 160 {} 159 {} 158 {} 157 {} 156 {} 155 {} 154 {} 153 {} 152 {} 151 {} 150 {} 149 {} 148 {} 147 {} 146 {} 145 {} 144 {} 143 {} 142 {} 141 {} 140 {} 139 {} 138 {} 137 {} 136 {} 135 {} 134 {} 133 {} 132 {} 131 {} 130 {} 129 {} 128 {} 127 {} 126 {} 125 {} 124 {} 123 {} 122 {} 121 {} 120 {} 119 {} 118 {} 117 {} 116 {} 115 {} 114 {} 113 {} 112 {} 111 {} 110 {} 109 {} 108 {} 107 {} 106 {} 105 {} 104 {} 103 {} 102 {} 101 {} 100 {} 99 {} 98 {} 97 {} 96 {} 95 {} 94 {} 93 {} 92 {} 91 {} 90 {} 89 {} 88 {} 87 {} 86 {} 85 {} 84 {} 83 {} 82 {} 81 {} 80 {} 79 {} 78 {} 77 {} 76 {} 75 {} 74 {} 73 {} 72 {} 71 {} 70 {} 69 {} 68 {} 67 {} 66 {} 65 {} 64 {} 63 {} 62 {} 61 {} 60 {} 59 {} 58 {} 57 {} 56 {} 55 {} 54 {} 53 {} 52 {} 51 {} 50 {} 49 {} 48 {} 47 {} 46 {} 45 {} 44 {} 43 {} 42 {} 41 {} 40 {} 39 {} 38 {} 37 {} 36 {} 35 {} 34 {} 33 {} 32 {} 31 {} 30 {} 29 {} 28 {} 27 {} 26 {} 25 {} 24 {} 23 {} 22 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.16.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.16.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +} {20 89.6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 19 6.29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 18 29.47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 17 47.59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 16 59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 15 28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 14 75.78.72.98.87.73.96.74.90.75.91.69.39.7 13 78.72.98.87.73.96.74.90.75.91.69.39.7 12 72.98.87.73.96.74.90.75.91.69.39.7 11 98.87.73.96.74.90.75.91.69.39.7 10 87.73.96.74.90.75.91.69.39.7 9 73.96.74.90.75.91.69.39.7 8 96.74.90.75.91.69.39.7 7 74.90.75.91.69.39.7 6 90.75.91.69.39.7 5 75.91.69.39.7 4 91.69.39.7 3 69.39.7 2 39.7 1 7 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 74.96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 19 96.97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 18 97.84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 17 84.86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 16 86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 15 32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 14 25.89.29.9.21.12.88.55.70.58.81.91.52.58 13 89.29.9.21.12.88.55.70.58.81.91.52.58 12 29.9.21.12.88.55.70.58.81.91.52.58 11 9.21.12.88.55.70.58.81.91.52.58 10 21.12.88.55.70.58.81.91.52.58 9 12.88.55.70.58.81.91.52.58 8 88.55.70.58.81.91.52.58 7 55.70.58.81.91.52.58 6 70.58.81.91.52.58 5 58.81.91.52.58 4 81.91.52.58 3 91.52.58 2 52.58 1 58 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 74.38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 19 38.46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 18 46.23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 17 23.61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 16 61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 15 3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 14 1.76.63.73.65.20.8.77.19.9.23.15.50.38 13 76.63.73.65.20.8.77.19.9.23.15.50.38 12 63.73.65.20.8.77.19.9.23.15.50.38 11 73.65.20.8.77.19.9.23.15.50.38 10 65.20.8.77.19.9.23.15.50.38 9 20.8.77.19.9.23.15.50.38 8 8.77.19.9.23.15.50.38 7 77.19.9.23.15.50.38 6 19.9.23.15.50.38 5 9.23.15.50.38 4 23.15.50.38 3 15.50.38 2 50.38 1 38 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 99.39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 19 39.54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 18 54.16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 17 16.85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 16 85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 15 22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 14 40.4.87.65.5.31.49.2.26.72.13.36.10.83 13 4.87.65.5.31.49.2.26.72.13.36.10.83 12 87.65.5.31.49.2.26.72.13.36.10.83 11 65.5.31.49.2.26.72.13.36.10.83 10 5.31.49.2.26.72.13.36.10.83 9 31.49.2.26.72.13.36.10.83 8 49.2.26.72.13.36.10.83 7 2.26.72.13.36.10.83 6 26.72.13.36.10.83 5 72.13.36.10.83 4 13.36.10.83 3 36.10.83 2 10.83 1 83 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 20 33.91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 19 91.8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 18 8.65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 17 65.85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 16 85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 15 55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 14 56.42.80.58.11.95.90.85.47.33.14.3.33.82 13 42.80.58.11.95.90.85.47.33.14.3.33.82 12 80.58.11.95.90.85.47.33.14.3.33.82 11 58.11.95.90.85.47.33.14.3.33.82 10 11.95.90.85.47.33.14.3.33.82 9 95.90.85.47.33.14.3.33.82 8 90.85.47.33.14.3.33.82 7 85.47.33.14.3.33.82 6 47.33.14.3.33.82 5 33.14.3.33.82 4 14.3.33.82 3 3.33.82 2 33.82 1 82 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {}} + +do_execsql_test 1.17.2.1 { + SELECT max(b) OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 95 95 84 84 84 84 84 84 84 84 83 83 83 83 83 83 83 83 83 82 82 17 7 5 {} {} {} {}} + +do_execsql_test 1.17.2.2 { + SELECT min(b) OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 {} {} {} {}} + +do_execsql_test 1.17.3.1 { + SELECT row_number() OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.17.3.2 { + SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.17.3.3 { + SELECT row_number() OVER ( ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.17.4.1 { + SELECT dense_rank() OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.17.4.2 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.17.4.3 { + SELECT dense_rank() OVER ( ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 3 3 3 4 4 5 6 6 7 8 8 8 9 9 9 10 10 10 11 12 12 13 13 13 14 14 15 16 16 16 17 17 17 18 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 45 45 46 46 46 46 47 48 49 50 51 52 53 53 54 54 54 55 56 56 56 56 57 57 57 57 58 59 59 60 60 61 62 63 63 63 64 65 66 67 68 69 69 69 70 70 70 71 71 71 71 71 72 72 72 73 74 74 75 75 76 77 77 78 78 78 79 80 81 81 81 81 82 82 82 83 84 84 85 86 86 86 87 87 87 88 88 88 88 88 89 89 89 90 91 91 91 92 92 92 93 93 94 94 95 95 95} + +do_execsql_test 1.17.4.4 { + SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 5 6 7 8 9 9 10 10 10 1 1 2 2 3 3 4 4 5 5 5 6 7 7 8 8 8 9 9 9 9 9 1 1 1 2 2 2 3 3 4 5 6 7 7 8 8 8 9 1 1 2 2 3 3 3 4 4 4 4 4 5 5 6 7 8 8 8 9 10 10 10 1 2 3 4 4 4 4 5 5 6 7 8 8 8 8 8 9 9 9 9 10 1 1 2 2 2 3 4 4 5 5 6 6 6 7 7 7 8 8 8 9 9 9 1 2 2 2 3 3 3 4 4 4 4 5 5 6 6 6 7 8 9 10 10 10 1 1 1 2 3 3 4 4 5 5 5 5 6 7 8 8 9 9 10 10 1 1 1 2 3 3 4 4 4 4 5 6 6 7 8 8 1 1 1 2 3 3 3 4 4 4 5 6 6 6 6 7 8 9 9 9 10 10 10} + +do_execsql_test 1.17.4.5 { + SELECT dense_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10} + +do_execsql_test 1.17.4.6 { + SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5} + +do_execsql_test 1.17.5.1 { + SELECT rank() OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {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} + +do_execsql_test 1.17.5.2 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23} + +do_execsql_test 1.17.5.3 { + SELECT rank() OVER ( ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 2 4 4 4 7 7 9 10 10 12 13 13 13 16 16 16 19 19 19 22 23 23 25 25 25 28 28 30 31 31 31 34 34 34 37 38 39 40 40 42 42 44 44 44 47 48 49 49 49 52 52 54 55 55 55 58 58 58 61 61 63 64 64 64 64 64 69 69 69 69 73 73 75 75 75 75 79 79 81 81 83 83 83 86 87 87 87 90 91 91 93 93 95 95 97 97 97 97 101 102 103 104 105 106 107 107 109 109 109 112 113 113 113 113 117 117 117 117 121 122 122 124 124 126 127 128 128 128 131 132 133 134 135 136 136 136 139 139 139 142 142 142 142 142 147 147 147 150 151 151 153 153 155 156 156 158 158 158 161 162 163 163 163 163 167 167 167 170 171 171 173 174 174 174 177 177 177 180 180 180 180 180 185 185 185 188 189 189 189 192 192 192 195 195 197 197 199 199 199} + +do_execsql_test 1.17.5.4 { + SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 2 3 4 4 4 7 8 9 10 11 11 13 13 13 1 1 3 3 5 5 7 7 9 9 9 12 13 13 15 15 15 18 18 18 18 18 1 1 1 4 4 4 7 7 9 10 11 12 12 14 14 14 17 1 1 3 3 5 5 5 8 8 8 8 8 13 13 15 16 17 17 17 20 21 21 21 1 2 3 4 4 4 4 8 8 10 11 12 12 12 12 12 17 17 17 17 21 1 1 3 3 3 6 7 7 9 9 11 11 11 14 14 14 17 17 17 20 20 20 1 2 2 2 5 5 5 8 8 8 8 12 12 14 14 14 17 18 19 20 20 20 1 1 1 4 5 5 7 7 9 9 9 9 13 14 15 15 17 17 19 19 1 1 1 4 5 5 7 7 7 7 11 12 12 14 15 15 1 1 1 4 5 5 5 8 8 8 11 12 12 12 12 16 17 18 18 18 21 21 21} + +do_execsql_test 1.17.5.5 { + SELECT rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 143 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 163 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179 179} + +do_execsql_test 1.17.5.6 { + SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 46 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 68 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88} + +do_execsql_test 1.17.6.1 { + SELECT + row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ), + rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ), + dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) + FROM t2 +} {1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 16 2 17 16 2 18 16 2 19 16 2 20 16 2 21 16 2 22 16 2 23 16 2 24 16 2 25 16 2 26 16 2 27 16 2 28 16 2 29 16 2 30 16 2 31 16 2 32 16 2 33 33 3 34 33 3 35 33 3 36 33 3 37 33 3 38 33 3 39 33 3 40 33 3 41 33 3 42 33 3 43 33 3 44 33 3 45 33 3 46 33 3 47 33 3 48 33 3 49 33 3 50 33 3 51 33 3 52 33 3 53 33 3 54 54 4 55 54 4 56 54 4 57 54 4 58 54 4 59 54 4 60 54 4 61 54 4 62 54 4 63 54 4 64 54 4 65 54 4 66 54 4 67 54 4 68 54 4 69 54 4 70 54 4 71 54 4 72 54 4 73 54 4 74 54 4 75 54 4 76 76 5 77 76 5 78 76 5 79 76 5 80 76 5 81 76 5 82 76 5 83 76 5 84 76 5 85 76 5 86 76 5 87 76 5 88 76 5 89 76 5 90 76 5 91 76 5 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 10 1 1 11 1 1 12 1 1 13 1 1 14 1 1 15 1 1 16 1 1 17 1 1 18 1 1 19 1 1 20 1 1 21 1 1 22 1 1 23 23 2 24 23 2 25 23 2 26 23 2 27 23 2 28 23 2 29 23 2 30 23 2 31 23 2 32 23 2 33 23 2 34 23 2 35 23 2 36 23 2 37 23 2 38 23 2 39 23 2 40 23 2 41 23 2 42 23 2 43 23 2 44 23 2 45 23 2 46 46 3 47 46 3 48 46 3 49 46 3 50 46 3 51 46 3 52 46 3 53 46 3 54 46 3 55 46 3 56 46 3 57 46 3 58 46 3 59 46 3 60 46 3 61 46 3 62 46 3 63 46 3 64 46 3 65 46 3 66 46 3 67 46 3 68 68 4 69 68 4 70 68 4 71 68 4 72 68 4 73 68 4 74 68 4 75 68 4 76 68 4 77 68 4 78 68 4 79 68 4 80 68 4 81 68 4 82 68 4 83 68 4 84 68 4 85 68 4 86 68 4 87 68 4 88 88 5 89 88 5 90 88 5 91 88 5 92 88 5 93 88 5 94 88 5 95 88 5 96 88 5 97 88 5 98 88 5 99 88 5 100 88 5 101 88 5 102 88 5 103 88 5 104 88 5 105 88 5 106 88 5 107 88 5 108 88 5 109 88 5 110 88 5} + + +do_test 1.17.7.1 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0100 0.0150 0.0200 0.0250 0.0300 0.0350 0.0400 0.0450 0.0500 0.0550 0.0600 0.0650 0.0700 0.0750 0.0800 0.0850 0.0900 0.0950 0.1000 0.1050 0.1100 0.1150 0.1200 0.1250 0.1300 0.1350 0.1400 0.1450 0.1500 0.1550 0.1600 0.1650 0.1700 0.1750 0.1800 0.1850 0.1900 0.1950 0.2000 0.2050 0.2100 0.2150 0.2200 0.2250 0.2300 0.2350 0.2400 0.2450 0.2500 0.2550 0.2600 0.2650 0.2700 0.2750 0.2800 0.2850 0.2900 0.2950 0.3000 0.3050 0.3100 0.3150 0.3200 0.3250 0.3300 0.3350 0.3400 0.3450 0.3500 0.3550 0.3600 0.3650 0.3700 0.3750 0.3800 0.3850 0.3900 0.3950 0.4000 0.4050 0.4100 0.4150 0.4200 0.4250 0.4300 0.4350 0.4400 0.4450 0.4500 0.4550 0.4600 0.4650 0.4700 0.4750 0.4800 0.4850 0.4900 0.4950 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5350 0.5400 0.5450 0.5500 0.5550 0.5600 0.5650 0.5700 0.5750 0.5800 0.5850 0.5900 0.5950 0.6000 0.6050 0.6100 0.6150 0.6200 0.6250 0.6300 0.6350 0.6400 0.6450 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6800 0.6850 0.6900 0.6950 0.7000 0.7050 0.7100 0.7150 0.7200 0.7250 0.7300 0.7350 0.7400 0.7450 0.7500 0.7550 0.7600 0.7650 0.7700 0.7750 0.7800 0.7850 0.7900 0.7950 0.8000 0.8050 0.8100 0.8150 0.8200 0.8250 0.8300 0.8350 0.8400 0.8450 0.8500 0.8550 0.8600 0.8650 0.8700 0.8750 0.8800 0.8850 0.8900 0.8950 0.9000 0.9050 0.9100 0.9150 0.9200 0.9250 0.9300 0.9350 0.9400 0.9450 0.9500 0.9550 0.9600 0.9650 0.9700 0.9750 0.9800 0.9850 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.7.2 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429 0.7143 0.7857 0.8571 0.9286 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0000 0.0526 0.1053 0.1579 0.2105 0.2632 0.3158 0.3684 0.4211 0.4737 0.5263 0.5789 0.6316 0.6842 0.7368 0.7895 0.8421 0.8947 0.9474 1.0000 0.0000 0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.7.3 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0050 0.0050 0.0150 0.0150 0.0150 0.0300 0.0300 0.0400 0.0450 0.0450 0.0550 0.0600 0.0600 0.0600 0.0750 0.0750 0.0750 0.0900 0.0900 0.0900 0.1050 0.1100 0.1100 0.1200 0.1200 0.1200 0.1350 0.1350 0.1450 0.1500 0.1500 0.1500 0.1650 0.1650 0.1650 0.1800 0.1850 0.1900 0.1950 0.1950 0.2050 0.2050 0.2150 0.2150 0.2150 0.2300 0.2350 0.2400 0.2400 0.2400 0.2550 0.2550 0.2650 0.2700 0.2700 0.2700 0.2850 0.2850 0.2850 0.3000 0.3000 0.3100 0.3150 0.3150 0.3150 0.3150 0.3150 0.3400 0.3400 0.3400 0.3400 0.3600 0.3600 0.3700 0.3700 0.3700 0.3700 0.3900 0.3900 0.4000 0.4000 0.4100 0.4100 0.4100 0.4250 0.4300 0.4300 0.4300 0.4450 0.4500 0.4500 0.4600 0.4600 0.4700 0.4700 0.4800 0.4800 0.4800 0.4800 0.5000 0.5050 0.5100 0.5150 0.5200 0.5250 0.5300 0.5300 0.5400 0.5400 0.5400 0.5550 0.5600 0.5600 0.5600 0.5600 0.5800 0.5800 0.5800 0.5800 0.6000 0.6050 0.6050 0.6150 0.6150 0.6250 0.6300 0.6350 0.6350 0.6350 0.6500 0.6550 0.6600 0.6650 0.6700 0.6750 0.6750 0.6750 0.6900 0.6900 0.6900 0.7050 0.7050 0.7050 0.7050 0.7050 0.7300 0.7300 0.7300 0.7450 0.7500 0.7500 0.7600 0.7600 0.7700 0.7750 0.7750 0.7850 0.7850 0.7850 0.8000 0.8050 0.8100 0.8100 0.8100 0.8100 0.8300 0.8300 0.8300 0.8450 0.8500 0.8500 0.8600 0.8650 0.8650 0.8650 0.8800 0.8800 0.8800 0.8950 0.8950 0.8950 0.8950 0.8950 0.9200 0.9200 0.9200 0.9350 0.9400 0.9400 0.9400 0.9550 0.9550 0.9550 0.9700 0.9700 0.9800 0.9800 0.9900 0.9900 0.9900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.7.4 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0714 0.1429 0.2143 0.2143 0.2143 0.4286 0.5000 0.5714 0.6429 0.7143 0.7143 0.8571 0.8571 0.8571 0.0000 0.0000 0.0952 0.0952 0.1905 0.1905 0.2857 0.2857 0.3810 0.3810 0.3810 0.5238 0.5714 0.5714 0.6667 0.6667 0.6667 0.8095 0.8095 0.8095 0.8095 0.8095 0.0000 0.0000 0.0000 0.1875 0.1875 0.1875 0.3750 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.8125 0.8125 0.8125 1.0000 0.0000 0.0000 0.0909 0.0909 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.3182 0.3182 0.5455 0.5455 0.6364 0.6818 0.7273 0.7273 0.7273 0.8636 0.9091 0.9091 0.9091 0.0000 0.0500 0.1000 0.1500 0.1500 0.1500 0.1500 0.3500 0.3500 0.4500 0.5000 0.5500 0.5500 0.5500 0.5500 0.5500 0.8000 0.8000 0.8000 0.8000 1.0000 0.0000 0.0000 0.0952 0.0952 0.0952 0.2381 0.2857 0.2857 0.3810 0.3810 0.4762 0.4762 0.4762 0.6190 0.6190 0.6190 0.7619 0.7619 0.7619 0.9048 0.9048 0.9048 0.0000 0.0476 0.0476 0.0476 0.1905 0.1905 0.1905 0.3333 0.3333 0.3333 0.3333 0.5238 0.5238 0.6190 0.6190 0.6190 0.7619 0.8095 0.8571 0.9048 0.9048 0.9048 0.0000 0.0000 0.0000 0.1579 0.2105 0.2105 0.3158 0.3158 0.4211 0.4211 0.4211 0.4211 0.6316 0.6842 0.7368 0.7368 0.8421 0.8421 0.9474 0.9474 0.0000 0.0000 0.0000 0.2000 0.2667 0.2667 0.4000 0.4000 0.4000 0.4000 0.6667 0.7333 0.7333 0.8667 0.9333 0.9333 0.0000 0.0000 0.0000 0.1364 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.4545 0.5000 0.5000 0.5000 0.5000 0.6818 0.7273 0.7727 0.7727 0.7727 0.9091 0.9091 0.9091} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.7.5 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER ( ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.0750 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.1850 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.2700 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.3850 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.4900 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.6000 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.7100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8100 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900 0.8900} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.7.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.1667 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.3556 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.5889 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.8333 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.2018 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.4128 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.6147 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982 0.7982} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.1 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0100 0.0149 0.0199 0.0249 0.0299 0.0348 0.0398 0.0448 0.0498 0.0547 0.0597 0.0647 0.0697 0.0746 0.0796 0.0846 0.0896 0.0945 0.0995 0.1045 0.1095 0.1144 0.1194 0.1244 0.1294 0.1343 0.1393 0.1443 0.1493 0.1542 0.1592 0.1642 0.1692 0.1741 0.1791 0.1841 0.1891 0.1940 0.1990 0.2040 0.2090 0.2139 0.2189 0.2239 0.2289 0.2338 0.2388 0.2438 0.2488 0.2537 0.2587 0.2637 0.2687 0.2736 0.2786 0.2836 0.2886 0.2935 0.2985 0.3035 0.3085 0.3134 0.3184 0.3234 0.3284 0.3333 0.3383 0.3433 0.3483 0.3532 0.3582 0.3632 0.3682 0.3731 0.3781 0.3831 0.3881 0.3930 0.3980 0.4030 0.4080 0.4129 0.4179 0.4229 0.4279 0.4328 0.4378 0.4428 0.4478 0.4527 0.4577 0.4627 0.4677 0.4726 0.4776 0.4826 0.4876 0.4925 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5323 0.5373 0.5423 0.5473 0.5522 0.5572 0.5622 0.5672 0.5721 0.5771 0.5821 0.5871 0.5920 0.5970 0.6020 0.6070 0.6119 0.6169 0.6219 0.6269 0.6318 0.6368 0.6418 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6766 0.6816 0.6866 0.6915 0.6965 0.7015 0.7065 0.7114 0.7164 0.7214 0.7264 0.7313 0.7363 0.7413 0.7463 0.7512 0.7562 0.7612 0.7662 0.7711 0.7761 0.7811 0.7861 0.7910 0.7960 0.8010 0.8060 0.8109 0.8159 0.8209 0.8259 0.8308 0.8358 0.8408 0.8458 0.8507 0.8557 0.8607 0.8657 0.8706 0.8756 0.8806 0.8856 0.8905 0.8955 0.9005 0.9055 0.9104 0.9154 0.9204 0.9254 0.9303 0.9353 0.9403 0.9453 0.9502 0.9552 0.9602 0.9652 0.9701 0.9751 0.9801 0.9851 0.9900 0.9950 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.2 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.2667 0.3333 0.4000 0.4667 0.5333 0.6000 0.6667 0.7333 0.8000 0.8667 0.9333 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0588 0.1176 0.1765 0.2353 0.2941 0.3529 0.4118 0.4706 0.5294 0.5882 0.6471 0.7059 0.7647 0.8235 0.8824 0.9412 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000 0.0476 0.0952 0.1429 0.1905 0.2381 0.2857 0.3333 0.3810 0.4286 0.4762 0.5238 0.5714 0.6190 0.6667 0.7143 0.7619 0.8095 0.8571 0.9048 0.9524 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0455 0.0909 0.1364 0.1818 0.2273 0.2727 0.3182 0.3636 0.4091 0.4545 0.5000 0.5455 0.5909 0.6364 0.6818 0.7273 0.7727 0.8182 0.8636 0.9091 0.9545 1.0000 0.0500 0.1000 0.1500 0.2000 0.2500 0.3000 0.3500 0.4000 0.4500 0.5000 0.5500 0.6000 0.6500 0.7000 0.7500 0.8000 0.8500 0.9000 0.9500 1.0000 0.0625 0.1250 0.1875 0.2500 0.3125 0.3750 0.4375 0.5000 0.5625 0.6250 0.6875 0.7500 0.8125 0.8750 0.9375 1.0000 0.0435 0.0870 0.1304 0.1739 0.2174 0.2609 0.3043 0.3478 0.3913 0.4348 0.4783 0.5217 0.5652 0.6087 0.6522 0.6957 0.7391 0.7826 0.8261 0.8696 0.9130 0.9565 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.3 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0050 0.0149 0.0149 0.0299 0.0299 0.0299 0.0398 0.0398 0.0448 0.0547 0.0547 0.0597 0.0746 0.0746 0.0746 0.0896 0.0896 0.0896 0.1045 0.1045 0.1045 0.1095 0.1194 0.1194 0.1343 0.1343 0.1343 0.1443 0.1443 0.1493 0.1642 0.1642 0.1642 0.1791 0.1791 0.1791 0.1841 0.1891 0.1940 0.2040 0.2040 0.2139 0.2139 0.2289 0.2289 0.2289 0.2338 0.2388 0.2537 0.2537 0.2537 0.2637 0.2637 0.2687 0.2836 0.2836 0.2836 0.2985 0.2985 0.2985 0.3085 0.3085 0.3134 0.3383 0.3383 0.3383 0.3383 0.3383 0.3582 0.3582 0.3582 0.3582 0.3682 0.3682 0.3881 0.3881 0.3881 0.3881 0.3980 0.3980 0.4080 0.4080 0.4229 0.4229 0.4229 0.4279 0.4428 0.4428 0.4428 0.4478 0.4577 0.4577 0.4677 0.4677 0.4776 0.4776 0.4975 0.4975 0.4975 0.4975 0.5025 0.5075 0.5124 0.5174 0.5224 0.5274 0.5373 0.5373 0.5522 0.5522 0.5522 0.5572 0.5771 0.5771 0.5771 0.5771 0.5970 0.5970 0.5970 0.5970 0.6020 0.6119 0.6119 0.6219 0.6219 0.6269 0.6318 0.6468 0.6468 0.6468 0.6517 0.6567 0.6617 0.6667 0.6716 0.6866 0.6866 0.6866 0.7015 0.7015 0.7015 0.7264 0.7264 0.7264 0.7264 0.7264 0.7413 0.7413 0.7413 0.7463 0.7562 0.7562 0.7662 0.7662 0.7711 0.7811 0.7811 0.7960 0.7960 0.7960 0.8010 0.8060 0.8259 0.8259 0.8259 0.8259 0.8408 0.8408 0.8408 0.8458 0.8557 0.8557 0.8607 0.8756 0.8756 0.8756 0.8905 0.8905 0.8905 0.9154 0.9154 0.9154 0.9154 0.9154 0.9303 0.9303 0.9303 0.9353 0.9502 0.9502 0.9502 0.9652 0.9652 0.9652 0.9751 0.9751 0.9851 0.9851 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.4 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0667 0.1333 0.2000 0.4000 0.4000 0.4000 0.4667 0.5333 0.6000 0.6667 0.8000 0.8000 1.0000 1.0000 1.0000 0.0909 0.0909 0.1818 0.1818 0.2727 0.2727 0.3636 0.3636 0.5000 0.5000 0.5000 0.5455 0.6364 0.6364 0.7727 0.7727 0.7727 1.0000 1.0000 1.0000 1.0000 1.0000 0.1765 0.1765 0.1765 0.3529 0.3529 0.3529 0.4706 0.4706 0.5294 0.5882 0.6471 0.7647 0.7647 0.9412 0.9412 0.9412 1.0000 0.0870 0.0870 0.1739 0.1739 0.3043 0.3043 0.3043 0.5217 0.5217 0.5217 0.5217 0.5217 0.6087 0.6087 0.6522 0.6957 0.8261 0.8261 0.8261 0.8696 1.0000 1.0000 1.0000 0.0476 0.0952 0.1429 0.3333 0.3333 0.3333 0.3333 0.4286 0.4286 0.4762 0.5238 0.7619 0.7619 0.7619 0.7619 0.7619 0.9524 0.9524 0.9524 0.9524 1.0000 0.0909 0.0909 0.2273 0.2273 0.2273 0.2727 0.3636 0.3636 0.4545 0.4545 0.5909 0.5909 0.5909 0.7273 0.7273 0.7273 0.8636 0.8636 0.8636 1.0000 1.0000 1.0000 0.0455 0.1818 0.1818 0.1818 0.3182 0.3182 0.3182 0.5000 0.5000 0.5000 0.5000 0.5909 0.5909 0.7273 0.7273 0.7273 0.7727 0.8182 0.8636 1.0000 1.0000 1.0000 0.1500 0.1500 0.1500 0.2000 0.3000 0.3000 0.4000 0.4000 0.6000 0.6000 0.6000 0.6000 0.6500 0.7000 0.8000 0.8000 0.9000 0.9000 1.0000 1.0000 0.1875 0.1875 0.1875 0.2500 0.3750 0.3750 0.6250 0.6250 0.6250 0.6250 0.6875 0.8125 0.8125 0.8750 1.0000 1.0000 0.1304 0.1304 0.1304 0.1739 0.3043 0.3043 0.3043 0.4348 0.4348 0.4348 0.4783 0.6522 0.6522 0.6522 0.6522 0.6957 0.7391 0.8696 0.8696 0.8696 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.5 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.0746 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.1841 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.2687 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.3831 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.4876 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.5970 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.7065 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8060 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 0.8856 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.6 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.1648 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.3516 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.5824 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 0.8242 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.2000 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.4091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.6091 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 0.7909 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.1 { + set myres {} + foreach r [db eval {SELECT ntile(100) OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 100.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.2 { + set myres {} + foreach r [db eval {SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.3 { + set myres {} + foreach r [db eval {SELECT ntile(102) OVER ( ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 98.0000 99.0000 99.0000 100.0000 101.0000 102.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.4 { + set myres {} + foreach r [db eval {SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000 11.0000 12.0000 13.0000 14.0000 15.0000 16.0000 17.0000 18.0000 19.0000 20.0000 21.0000 22.0000 23.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.5 { + set myres {} + foreach r [db eval {SELECT ntile(104) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.6 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 1.17.8.7 { + set myres {} + foreach r [db eval {SELECT ntile(105) OVER ( ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 8.0000 8.0000 9.0000 9.0000 10.0000 10.0000 11.0000 11.0000 12.0000 12.0000 13.0000 13.0000 14.0000 14.0000 15.0000 15.0000 16.0000 16.0000 17.0000 17.0000 18.0000 18.0000 19.0000 19.0000 20.0000 20.0000 21.0000 21.0000 22.0000 22.0000 23.0000 23.0000 24.0000 24.0000 25.0000 25.0000 26.0000 26.0000 27.0000 27.0000 28.0000 28.0000 29.0000 29.0000 30.0000 30.0000 31.0000 31.0000 32.0000 32.0000 33.0000 33.0000 34.0000 34.0000 35.0000 35.0000 36.0000 36.0000 37.0000 37.0000 38.0000 38.0000 39.0000 39.0000 40.0000 40.0000 41.0000 41.0000 42.0000 42.0000 43.0000 43.0000 44.0000 44.0000 45.0000 45.0000 46.0000 46.0000 47.0000 47.0000 48.0000 48.0000 49.0000 49.0000 50.0000 50.0000 51.0000 51.0000 52.0000 52.0000 53.0000 53.0000 54.0000 54.0000 55.0000 55.0000 56.0000 56.0000 57.0000 57.0000 58.0000 58.0000 59.0000 59.0000 60.0000 60.0000 61.0000 61.0000 62.0000 62.0000 63.0000 63.0000 64.0000 64.0000 65.0000 65.0000 66.0000 66.0000 67.0000 67.0000 68.0000 68.0000 69.0000 69.0000 70.0000 70.0000 71.0000 71.0000 72.0000 72.0000 73.0000 73.0000 74.0000 74.0000 75.0000 75.0000 76.0000 76.0000 77.0000 77.0000 78.0000 78.0000 79.0000 79.0000 80.0000 80.0000 81.0000 81.0000 82.0000 82.0000 83.0000 83.0000 84.0000 84.0000 85.0000 85.0000 86.0000 86.0000 87.0000 87.0000 88.0000 88.0000 89.0000 89.0000 90.0000 90.0000 91.0000 91.0000 92.0000 92.0000 93.0000 93.0000 94.0000 94.0000 95.0000 95.0000 96.0000 96.0000 97.0000 98.0000 99.0000 100.0000 101.0000 102.0000 103.0000 104.0000 105.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 1.17.9.1 { + SELECT last_value(a+b) OVER ( ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 {} {} {} {}} + +do_execsql_test 1.17.9.2 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {223 223 223 223 223 223 223 223 223 223 223 {} {} {} {} 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 {} {} {} {} 280 280 280 280 280 280 280 280 280 280 280 280 280 {} {} {} {} 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 279 {} {} {} {} 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 {} {} {} {} 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 206 {} {} {} {} 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 {} {} {} {} 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 207 {} {} {} {} 232 232 232 232 232 232 232 232 232 232 232 232 {} {} {} {} 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 {} {} {} {}} + +do_execsql_test 1.17.9.3 { + SELECT last_value(a+b) OVER ( ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 {} {} {} {}} + +do_execsql_test 1.17.9.4 { + SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {240 240 240 240 240 240 240 240 240 240 240 {} {} {} {} 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 {} {} {} {} 280 280 280 280 280 280 280 280 280 280 280 280 280 {} {} {} {} 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 {} {} {} {} 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 171 {} {} {} {} 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 274 {} {} {} {} 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 226 {} {} {} {} 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 124 {} {} {} {} 198 198 198 198 198 198 198 198 198 198 198 198 {} {} {} {} 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 276 {} {} {} {}} + +do_execsql_test 1.17.9.5 { + SELECT last_value(a+b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 229 {} {} {} {}} + +do_execsql_test 1.17.9.6 { + SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.10.1 { + SELECT nth_value(b,b+1) OVER (ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {23 78 85 29 84 51 93 91 68 74 65 12 4 22 37 15 53 8 16 29 8 34 3 76 73 63 90 47 98 47 90 73 20 89 91 22 77 73 42 41 32 55 79 51 74 44 81 7 65 8 43 80 8 89 90 29 36 15 42 9 9 41 20 16 11 87 20 90 84 80 41 37 34 9 75 63 34 8 8 81 95 31 74 36 41 99 90 91 99 13 2 35 33 36 38 37 20 75 17 {} 5 34 58 33 19 31 50 34 23 5 72 90 11 85 90 36 2 {} 39 27 {} {} 64 2 74 95 37 {} 58 {} 34 44 {} {} 30 70 47 {} 7 {} 15 {} {} 12 33 36 99 17 {} {} 44 {} {} 12 {} {} {} 34 {} {} {} {} 36 44 {} 30 30 10 {} {} {} {} {} 30 {} {} {} 84 {} {} {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.10.2 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {80 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 21 {} {} {} 31 {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} 72 {} {} {} 82 {} {} {} {} {} {} {} {} {} {} {} {} 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 64 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 5 {} {} {} {} {} {} {} {} {} {} {} {} 76 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 27 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.10.3 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {2 3 3 5 5 6 7 7 8 9 9 10 11 12 12 13 13 14 15 15 16 16 19 20 21 22 22 23 23 25 26 26 27 28 29 29 30 31 32 33 33 33 34 34 34 35 36 36 37 37 38 39 39 40 41 41 42 43 44 44 46 47 47 49 50 51 52 53 55 55 56 56 57 58 58 58 59 59 59 60 61 62 63 64 65 65 67 68 69 72 72 73 73 74 74 74 75 75 76 77 78 80 81 81 83 84 84 85 85 86 87 88 89 89 90 90 91 91 91 91 93 93 94 95 95 96 97 98 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.10.4 { + SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {30 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 21 31 91 91 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 22 22 32 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 33 33 83 93 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 44 84 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 55 65 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 36 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 57 67 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 78 88 98 {} {} {} {} {} {} {} {} {} {} {} {} {} 59 59 69 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.10.5 { + SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {80 84 22 2 34 41 85 23 24 34 25 12 13 11 72 3 85 95 4 75 85 21 65 73 44 31 62 42 4 3 73 13 2 95 56 56 43 2 25 33 83 73 34 72 26 43 13 82 46 16 13 15 65 66 74 14 77 94 57 95 73 65 35 26 16 97 4 97 67 95 98 65 44 5 74 95 68 57 47 26 78 27 5 64 99 8 78 16 16 26 78 27 5 16 99 29 97 96 98 36 79 49 7 46 76 59 {} 58 38 7 5 56 {} 88 59 {} 39 26 {} 56 87 {} 88 76 58 67 77 {} 9 79 49 37 88 {} {} {} 28 98 99 {} 59 39 {} 58 {} {} {} 99 27 39 {} 29 {} {} 8 {} {} {} 69 49 39 88 {} {} {} 38 99 {} {} {} {} 29 {} 89 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.10.6 { + SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.11.1 { + SELECT first_value(b) OVER (ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {23 99 26 33 2 89 81 96 59 38 68 39 62 91 46 6 99 97 27 46 78 54 97 8 67 29 93 84 77 23 16 16 93 65 35 47 7 86 74 61 91 85 24 85 43 59 12 32 56 3 91 22 90 55 15 28 89 25 47 1 56 40 43 56 16 75 36 89 98 76 81 4 94 42 30 78 33 29 53 63 2 87 37 80 84 72 41 9 61 73 95 65 13 58 96 98 1 21 74 65 35 5 73 11 51 87 41 12 8 20 31 31 15 95 22 73 79 88 34 8 11 49 34 90 59 96 60 55 75 77 44 2 7 85 57 74 29 70 59 19 39 26 26 47 80 90 36 58 47 9 72 72 66 33 93 75 64 81 9 23 37 13 12 14 62 91 36 91 33 15 34 36 99 3 95 69 58 52 30 50 84 10 84 33 21 39 44 58 30 38 34 83 27 82 17 7 5 {} {} {} {}} + +do_execsql_test 1.17.11.2 { + SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {80 20 90 60 70 80 90 30 50 10 30 {} {} {} {} 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 {} {} {} {} 22 42 2 72 12 22 2 72 72 12 62 52 82 {} {} {} {} 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 {} {} {} {} 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 {} {} {} {} 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 {} {} {} {} 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 {} {} {} {} 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 {} {} {} {} 28 98 78 58 98 8 88 8 58 58 58 38 {} {} {} {} 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39 {} {} {} {}} + +do_execsql_test 1.17.11.3 { + SELECT first_value(b) OVER ( ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {2 2 3 3 4 5 5 6 7 7 7 8 8 8 9 9 9 10 11 11 12 12 12 13 13 14 15 15 15 16 16 16 17 19 20 21 21 22 22 23 23 23 24 25 26 26 26 27 27 28 29 29 29 30 30 30 31 31 32 33 33 33 33 33 34 34 34 34 35 35 36 36 36 36 37 37 38 38 39 39 39 40 41 41 41 42 43 43 44 44 46 46 47 47 47 47 49 50 51 52 53 54 55 55 56 56 56 57 58 58 58 58 59 59 59 59 60 61 61 62 62 63 64 65 65 65 66 67 68 69 70 72 72 72 73 73 73 74 74 74 74 74 75 75 75 76 77 77 78 78 79 80 80 81 81 81 82 83 84 84 84 84 85 85 85 86 87 87 88 89 89 89 90 90 90 91 91 91 91 91 93 93 93 94 95 95 95 96 96 96 97 97 98 98 99 99 99 {} {} {} {}} + +do_execsql_test 1.17.11.4 { + SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {30 30 40 50 60 70 80 80 90 90 90 {} {} {} {} 21 21 31 31 41 41 41 51 61 61 81 81 81 91 91 91 91 91 {} {} {} {} 12 12 22 22 32 42 52 62 62 72 72 72 82 {} {} {} {} 23 23 23 33 33 33 33 33 43 43 53 63 73 73 73 83 93 93 93 {} {} {} {} 34 34 34 44 44 54 64 74 74 74 74 74 84 84 84 84 94 {} {} {} {} 15 25 35 35 55 55 65 65 65 75 75 75 85 85 85 95 95 95 {} {} {} {} 26 26 26 36 36 36 36 46 46 56 56 56 66 76 86 96 96 96 {} {} {} {} 27 27 37 37 47 47 47 47 57 67 77 77 87 87 97 97 {} {} {} {} 38 38 58 58 58 58 68 78 78 88 98 98 {} {} {} {} 29 29 29 39 39 39 49 59 59 59 59 69 79 89 89 89 99 99 99 {} {} {} {}} + +do_execsql_test 1.17.11.5 { + SELECT first_value(b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {80 20 90 60 70 80 90 30 50 10 30 41 81 91 61 91 91 1 81 41 61 1 21 11 51 41 31 31 11 81 91 91 21 2 62 12 32 22 42 2 72 12 22 2 72 72 12 62 52 82 23 33 93 23 93 43 3 43 33 53 63 73 13 73 73 33 93 23 13 33 3 33 83 74 74 54 84 74 24 4 94 84 74 34 34 44 74 64 14 34 84 84 44 34 65 35 85 85 55 15 25 75 95 65 65 35 5 15 95 55 75 85 75 15 95 5 26 96 46 6 46 16 16 86 56 56 56 16 36 76 96 96 26 26 36 66 36 36 97 27 97 67 77 47 7 47 87 37 87 77 7 57 47 47 37 27 17 7 38 68 78 8 28 98 78 58 98 8 88 8 58 58 58 38 99 89 59 39 99 29 59 89 89 29 9 79 49 59 29 59 19 39 9 9 99 69 39 {} {} {} {}} + +do_execsql_test 1.17.11.6 { + SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.12.1 { + SELECT lead(b,b) OVER (ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 4 61 42 8 35 77 7 81 96 9 11 89 32 53 91 30 51 56 54 73 22 59 75 74 78 8 16 65 15 8 31 87 90 12 32 96 74 76 37 85 90 15 35 2 60 36 75 9 51 47 63 51 90 26 42 26 8 76 80 90 37 87 56 79 5 87 8 2 39 73 64 36 90 72 78 36 73 51 33 20 41 2 26 37 33 8 14 33 81 55 1 9 12 39 64 87 72 34 82 21 34 99 62 74 41 69 22 75 27 58 8 79 77 26 26 55 {} 29 30 7 {} 66 55 2 34 64 {} 33 {} 44 84 {} {} 95 85 19 {} 83 {} 91 {} {} 9 50 91 33 34 {} {} 84 {} 7 9 {} {} {} 44 {} {} {} {} 91 84 {} 95 95 52 {} {} {} {} {} 21 {} {} {} 58 {} {} {} {} {} {} {} 83 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.12.2 { + SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 81 {} {} {} 21 {} {} {} {} {} {} {} {} {} {} {} 12 {} 62 {} {} {} 12 {} {} {} 72 {} {} {} {} {} {} {} {} {} {} {} {} 53 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 95 {} {} {} {} {} {} 85 {} {} {} {} {} {} {} {} {} {} {} {} 56 {} 36 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 57 {} {} {} {} {} 7 {} {} {} {} {} {} {} {} {} {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.12.3 { + SELECT lead(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 1 2 2 3 3 5 5 7 7 8 8 9 9 10 11 12 12 13 13 14 15 16 16 17 19 20 21 22 23 23 24 25 26 26 27 28 29 30 31 31 33 33 33 33 34 34 35 36 36 36 37 37 38 39 39 40 41 41 42 43 44 46 47 47 47 47 49 51 52 53 54 55 56 56 57 58 58 58 59 59 59 61 61 62 63 65 65 65 67 69 70 72 72 73 74 74 74 74 75 76 77 78 80 81 81 83 84 84 84 85 85 87 87 88 89 89 90 90 90 91 91 91 93 93 95 95 96 96 97 98 99 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.12.4 { + SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 80 {} {} {} {} {} {} {} {} {} {} {} {} {} 1 11 61 81 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 12 12 72 82 {} {} {} {} {} {} {} {} {} {} {} {} 13 23 63 73 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 34 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 25 35 85 85 95 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 26 76 86 96 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 37 47 47 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 58 58 68 {} {} {} {} {} {} {} {} {} {} {} {} {} 39 49 59 99 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.12.5 { + SELECT lead(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 64 42 81 94 1 44 73 74 44 85 22 33 41 72 93 34 65 54 5 15 81 15 63 84 21 2 62 54 93 43 33 2 75 16 16 23 12 85 62 13 53 94 12 75 23 73 72 26 96 33 55 25 96 74 34 47 84 37 55 53 25 84 75 86 36 54 36 36 55 68 84 84 95 74 65 27 37 87 76 78 57 95 34 99 58 17 96 46 76 78 57 95 86 99 89 36 16 68 96 89 89 47 95 56 59 {} 88 8 97 85 16 {} 78 79 39 59 36 {} 46 77 {} 78 56 98 36 97 {} 59 89 89 47 78 {} {} {} 38 68 58 {} 58 38 {} 98 {} {} {} 19 57 9 {} 9 {} {} 7 {} {} {} 39 89 38 78 39 {} {} 8 19 {} {} {} {} 89 {} 39 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 9 {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.12.6 { + SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.13.1 { + SELECT lag(b,b) OVER (ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} 26 {} {} {} {} {} {} {} {} {} {} 38 {} {} {} {} {} {} {} 6 {} 0 {} {} {} 81 46 6 {} {} 74 {} 23 {} {} {} {} {} 27 {} 99 {} 35 6 {} 12 {} 23 {} 41 61 84 {} 93 39 47 2 54 46 96 56 {} 16 {} {} {} {} 89 {} 16 43 74 85 56 29 99 53 {} 59 33 23 91 59 53 84 99 {} 93 63 47 41 74 98 33 67 35 75 1 23 13 55 27 75 98 35 73 63 2 21 27 13 24 86 23 84 31 20 94 61 65 75 23 36 94 55 90 41 77 96 56 29 40 12 89 63 11 5 73 79 1 16 28 31 73 5 39 53 63 41 11 40 2 13 33 9 29 90 47 72 9 73 30 44 33 74 93 29 74 42 34 63 41 34 96 47 77 1 36 74 72 14 36 26 77 9 72 64 8 91 31 52 30 83} + +do_execsql_test 1.17.13.2 { + SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 {} 81 {} {} {} {} 1 {} {} {} 41 {} {} {} {} {} {} 22 {} {} {} 12 {} {} 62 {} {} {} {} {} {} {} {} {} 23 {} {} {} {} {} {} {} {} {} {} {} 43 {} 23 {} {} {} {} {} {} {} {} 54 {} {} {} {} {} {} {} {} 74 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 75 {} {} {} {} {} {} 55 {} 75 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 47 {} {} {} {} {} 27 7 {} {} {} {} {} {} {} {} {} 68 {} 8 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 89 {} {} {} {} {} {} {} 29 9 {} {} {}} + +do_execsql_test 1.17.13.3 { + SELECT lag(b,b) OVER ( ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 0 1 1 1 2 2 2 2 2 2 2 2 3 3 3 4 5 5 5 6 6 6 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 10 11 11 11 11 11 12 12 12 12 12 12 13 13 13 14 14 15 15 15 15 15 16 16 16 16 17 19 19 20 20 21 21 22 22 22 22 23 23 23 23 23 23 24 25 25 25 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27 27 27 27 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 37 38 38 38 39 39 39 39 39 39 39 40 41 41 41 41 41 42 43 43 44 43 44 44 44 44 46 46 46 47 47 47 47 47 47 47 49 50} + +do_execsql_test 1.17.13.4 { + SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 2 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.13.5 { + SELECT lag(b,b) OVER ( ORDER BY b%10,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} 30 {} {} {} {} {} {} {} 91 {} {} {} 61 20 81 {} {} {} 0 1 {} {} {} 41 91 {} 11 70 91 0 22 {} 81 61 12 {} {} 62 {} 0 {} 31 81 {} 91 {} 81 23 61 41 90 90 {} 82 {} {} 21 {} 72 43 32 23 42 {} 30 80 1 {} 60 93 54 {} 90 50 82 23 12 81 11 74 43 90 30 52 53 81 63 41 81 2 34 54 31 30 42 2 3 75 44 91 93 12 31 22 55 41 75 84 1 83 15 74 35 5 22 13 33 3 85 44 23 62 12 5 15 55 33 25 75 12 75 2 74 33 85 36 55 53 75 73 83 47 65 35 5 96 36 27 7 46 84 74 47 36 33 74 15 13 68 94 8 75 15 95 66 54 74 96 97 4 7 16 44 34 37 89 5 36 36 68 96 58 47 29 9 35 56 7} + +do_execsql_test 1.17.13.6 { + SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {0 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.14.1 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {23.99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 38.68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 68.39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 6.99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 27.46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 46.78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 54.97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 97.8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 67.29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 86.74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 24.85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 32.56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 28.89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 25.47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 40.43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 43.56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 56.16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 16.75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 89.98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 76.81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 4.94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 94.42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 42.30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 78.33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 53.63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 63.2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 61.73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 98.1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 1.21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 65.35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 35.5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 5.73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 51.87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 87.41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 41.12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 20.31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 31.15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 22.73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 73.79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 79.88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 88.34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 8.11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 11.49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 49.34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 96.60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 60.55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 55.75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 77.44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 44.2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 2.7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 7.85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 85.57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 57.74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 74.29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 29.70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 70.59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 59.19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 19.39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 39.26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 26.47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 80.90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 90.36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 47.9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 72.66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 66.33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 93.75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 75.64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 64.81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 81.9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 9.23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 23.37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 37.13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 13.12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 12.14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 14.62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 62.91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 91.33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 15.34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 34.36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 36.99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 99.3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 3.95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 95.69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 69.58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 58.52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 52.30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 30.50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 50.84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 10.84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 84.33.21.39.44.58.30.38.34.83.27.82.17.7.5 33.21.39.44.58.30.38.34.83.27.82.17.7.5 21.39.44.58.30.38.34.83.27.82.17.7.5 39.44.58.30.38.34.83.27.82.17.7.5 44.58.30.38.34.83.27.82.17.7.5 58.30.38.34.83.27.82.17.7.5 30.38.34.83.27.82.17.7.5 38.34.83.27.82.17.7.5 34.83.27.82.17.7.5 83.27.82.17.7.5 27.82.17.7.5 82.17.7.5 17.7.5 7.5 5 {} {} {} {}} + +do_execsql_test 1.17.14.2 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {80.20.90.60.70.80.90.30.50.10.30 20.90.60.70.80.90.30.50.10.30 90.60.70.80.90.30.50.10.30 60.70.80.90.30.50.10.30 70.80.90.30.50.10.30 80.90.30.50.10.30 90.30.50.10.30 30.50.10.30 50.10.30 10.30 30 {} {} {} {} 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21 41.61.1.21.11.51.41.31.31.11.81.91.91.21 61.1.21.11.51.41.31.31.11.81.91.91.21 1.21.11.51.41.31.31.11.81.91.91.21 21.11.51.41.31.31.11.81.91.91.21 11.51.41.31.31.11.81.91.91.21 51.41.31.31.11.81.91.91.21 41.31.31.11.81.91.91.21 31.31.11.81.91.91.21 31.11.81.91.91.21 11.81.91.91.21 81.91.91.21 91.91.21 91.21 21 {} {} {} {} 22.42.2.72.12.22.2.72.72.12.62.52.82 42.2.72.12.22.2.72.72.12.62.52.82 2.72.12.22.2.72.72.12.62.52.82 72.12.22.2.72.72.12.62.52.82 12.22.2.72.72.12.62.52.82 22.2.72.72.12.62.52.82 2.72.72.12.62.52.82 72.72.12.62.52.82 72.12.62.52.82 12.62.52.82 62.52.82 52.82 82 {} {} {} {} 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83 53.63.73.13.73.73.33.93.23.13.33.3.33.83 63.73.13.73.73.33.93.23.13.33.3.33.83 73.13.73.73.33.93.23.13.33.3.33.83 13.73.73.33.93.23.13.33.3.33.83 73.73.33.93.23.13.33.3.33.83 73.33.93.23.13.33.3.33.83 33.93.23.13.33.3.33.83 93.23.13.33.3.33.83 23.13.33.3.33.83 13.33.3.33.83 33.3.33.83 3.33.83 33.83 83 {} {} {} {} 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34 94.84.74.34.34.44.74.64.14.34.84.84.44.34 84.74.34.34.44.74.64.14.34.84.84.44.34 74.34.34.44.74.64.14.34.84.84.44.34 34.34.44.74.64.14.34.84.84.44.34 34.44.74.64.14.34.84.84.44.34 44.74.64.14.34.84.84.44.34 74.64.14.34.84.84.44.34 64.14.34.84.84.44.34 14.34.84.84.44.34 34.84.84.44.34 84.84.44.34 84.44.34 44.34 34 {} {} {} {} 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5 95.65.65.35.5.15.95.55.75.85.75.15.95.5 65.65.35.5.15.95.55.75.85.75.15.95.5 65.35.5.15.95.55.75.85.75.15.95.5 35.5.15.95.55.75.85.75.15.95.5 5.15.95.55.75.85.75.15.95.5 15.95.55.75.85.75.15.95.5 95.55.75.85.75.15.95.5 55.75.85.75.15.95.5 75.85.75.15.95.5 85.75.15.95.5 75.15.95.5 15.95.5 95.5 5 {} {} {} {} 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.56.16.36.76.96.96.26.26.36.66.36.36 56.56.16.36.76.96.96.26.26.36.66.36.36 56.16.36.76.96.96.26.26.36.66.36.36 16.36.76.96.96.26.26.36.66.36.36 36.76.96.96.26.26.36.66.36.36 76.96.96.26.26.36.66.36.36 96.96.26.26.36.66.36.36 96.26.26.36.66.36.36 26.26.36.66.36.36 26.36.66.36.36 36.66.36.36 66.36.36 36.36 36 {} {} {} {} 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7 7.47.87.37.87.77.7.57.47.47.37.27.17.7 47.87.37.87.77.7.57.47.47.37.27.17.7 87.37.87.77.7.57.47.47.37.27.17.7 37.87.77.7.57.47.47.37.27.17.7 87.77.7.57.47.47.37.27.17.7 77.7.57.47.47.37.27.17.7 7.57.47.47.37.27.17.7 57.47.47.37.27.17.7 47.47.37.27.17.7 47.37.27.17.7 37.27.17.7 27.17.7 17.7 7 {} {} {} {} 28.98.78.58.98.8.88.8.58.58.58.38 98.78.58.98.8.88.8.58.58.58.38 78.58.98.8.88.8.58.58.58.38 58.98.8.88.8.58.58.58.38 98.8.88.8.58.58.58.38 8.88.8.58.58.58.38 88.8.58.58.58.38 8.58.58.58.38 58.58.58.38 58.58.38 58.38 38 {} {} {} {} 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39 {} {} {} {}} + +do_execsql_test 1.17.14.3 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {2.2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 2.3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 3.4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 4.5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 5.6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 6.7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 7.8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 8.9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 9.10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 10.11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 11.12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 12.13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 13.14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 14.15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 15.16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 16.17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 17.19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 19.20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 20.21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 21.22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 22.23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 23.24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 24.25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 25.26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 26.27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 27.28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 28.29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 29.30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 30.31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 31.32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 32.33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 33.34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 34.35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 35.36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 36.37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 37.38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 38.39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 39.40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 40.41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 41.42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 42.43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 43.44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 44.46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 46.47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 47.49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 49.50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 50.51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 51.52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 52.53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 53.54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 54.55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 55.56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 56.57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 57.58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 58.59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 59.60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 60.61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 61.62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 62.63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 63.64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 64.65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 65.66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 66.67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 67.68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 68.69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 69.70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 70.72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 72.73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 73.74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 74.75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 75.76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 76.77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 77.78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 78.79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 79.80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 80.81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 81.82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 82.83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 83.84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 84.85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 85.86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 86.87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 87.88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 88.89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 89.90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 90.91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 91.93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 93.94.95.95.95.96.96.96.97.97.98.98.99.99.99 94.95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.95.96.96.96.97.97.98.98.99.99.99 95.95.96.96.96.97.97.98.98.99.99.99 95.96.96.96.97.97.98.98.99.99.99 96.96.96.97.97.98.98.99.99.99 96.96.97.97.98.98.99.99.99 96.97.97.98.98.99.99.99 97.97.98.98.99.99.99 97.98.98.99.99.99 98.98.99.99.99 98.99.99.99 99.99.99 99.99 99 {} {} {} {}} + +do_execsql_test 1.17.14.4 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {30.30.40.50.60.70.80.80.90.90.90 30.40.50.60.70.80.80.90.90.90 40.50.60.70.80.80.90.90.90 50.60.70.80.80.90.90.90 60.70.80.80.90.90.90 70.80.80.90.90.90 80.80.90.90.90 80.90.90.90 90.90.90 90.90 90 {} {} {} {} 21.21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 21.31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 31.41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.41.51.61.61.81.81.81.91.91.91.91.91 41.41.51.61.61.81.81.81.91.91.91.91.91 41.51.61.61.81.81.81.91.91.91.91.91 51.61.61.81.81.81.91.91.91.91.91 61.61.81.81.81.91.91.91.91.91 61.81.81.81.91.91.91.91.91 81.81.81.91.91.91.91.91 81.81.91.91.91.91.91 81.91.91.91.91.91 91.91.91.91.91 91.91.91.91 91.91.91 91.91 91 {} {} {} {} 12.12.22.22.32.42.52.62.62.72.72.72.82 12.22.22.32.42.52.62.62.72.72.72.82 22.22.32.42.52.62.62.72.72.72.82 22.32.42.52.62.62.72.72.72.82 32.42.52.62.62.72.72.72.82 42.52.62.62.72.72.72.82 52.62.62.72.72.72.82 62.62.72.72.72.82 62.72.72.72.82 72.72.72.82 72.72.82 72.82 82 {} {} {} {} 23.23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 23.33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.33.43.43.53.63.73.73.73.83.93.93.93 33.33.43.43.53.63.73.73.73.83.93.93.93 33.43.43.53.63.73.73.73.83.93.93.93 43.43.53.63.73.73.73.83.93.93.93 43.53.63.73.73.73.83.93.93.93 53.63.73.73.73.83.93.93.93 63.73.73.73.83.93.93.93 73.73.73.83.93.93.93 73.73.83.93.93.93 73.83.93.93.93 83.93.93.93 93.93.93 93.93 93 {} {} {} {} 34.34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 34.44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.44.54.64.74.74.74.74.74.84.84.84.84.94 44.54.64.74.74.74.74.74.84.84.84.84.94 54.64.74.74.74.74.74.84.84.84.84.94 64.74.74.74.74.74.84.84.84.84.94 74.74.74.74.74.84.84.84.84.94 74.74.74.74.84.84.84.84.94 74.74.74.84.84.84.84.94 74.74.84.84.84.84.94 74.84.84.84.84.94 84.84.84.84.94 84.84.84.94 84.84.94 84.94 94 {} {} {} {} 15.25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 25.35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 35.55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.55.65.65.65.75.75.75.85.85.85.95.95.95 55.65.65.65.75.75.75.85.85.85.95.95.95 65.65.65.75.75.75.85.85.85.95.95.95 65.65.75.75.75.85.85.85.95.95.95 65.75.75.75.85.85.85.95.95.95 75.75.75.85.85.85.95.95.95 75.75.85.85.85.95.95.95 75.85.85.85.95.95.95 85.85.85.95.95.95 85.85.95.95.95 85.95.95.95 95.95.95 95.95 95 {} {} {} {} 26.26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 26.36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.36.46.46.56.56.56.66.76.86.96.96.96 36.36.46.46.56.56.56.66.76.86.96.96.96 36.46.46.56.56.56.66.76.86.96.96.96 46.46.56.56.56.66.76.86.96.96.96 46.56.56.56.66.76.86.96.96.96 56.56.56.66.76.86.96.96.96 56.56.66.76.86.96.96.96 56.66.76.86.96.96.96 66.76.86.96.96.96 76.86.96.96.96 86.96.96.96 96.96.96 96.96 96 {} {} {} {} 27.27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 27.37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.37.47.47.47.47.57.67.77.77.87.87.97.97 37.47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.47.57.67.77.77.87.87.97.97 47.47.47.57.67.77.77.87.87.97.97 47.47.57.67.77.77.87.87.97.97 47.57.67.77.77.87.87.97.97 57.67.77.77.87.87.97.97 67.77.77.87.87.97.97 77.77.87.87.97.97 77.87.87.97.97 87.87.97.97 87.97.97 97.97 97 {} {} {} {} 38.38.58.58.58.58.68.78.78.88.98.98 38.58.58.58.58.68.78.78.88.98.98 58.58.58.58.68.78.78.88.98.98 58.58.58.68.78.78.88.98.98 58.58.68.78.78.88.98.98 58.68.78.78.88.98.98 68.78.78.88.98.98 78.78.88.98.98 78.88.98.98 88.98.98 98.98 98 {} {} {} {} 29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.39.49.59.59.59.59.69.79.89.89.89.99.99.99 39.49.59.59.59.59.69.79.89.89.89.99.99.99 49.59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.59.69.79.89.89.89.99.99.99 59.59.59.69.79.89.89.89.99.99.99 59.59.69.79.89.89.89.99.99.99 59.69.79.89.89.89.99.99.99 69.79.89.89.89.99.99.99 79.89.89.89.99.99.99 89.89.89.99.99.99 89.89.99.99.99 89.99.99.99 99.99.99 99.99 99 {} {} {} {}} + +do_execsql_test 1.17.14.5 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t2 +} {80.20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 20.90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 60.70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 70.80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 80.90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 90.30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 50.10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 10.30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 30.41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 61.1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 1.21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 51.41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 41.31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 31.11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 11.81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 81.91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 91.21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 21.2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 32.22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 42.2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 22.2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 2.72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 72.12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 12.62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 62.52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 52.82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 82.23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 43.33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 53.63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 63.73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 73.33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 93.23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 23.13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 13.33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 3.33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 33.83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 83.74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 54.84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 24.4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 4.94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 94.84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 74.64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 64.14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 14.34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 84.44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 44.34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 34.65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 25.75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 65.35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 35.5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 55.75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 85.75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 75.15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 15.95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 95.5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 5.26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 6.46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 46.16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 86.56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 56.16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 16.36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 76.96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 96.26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 26.36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 66.36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 36.97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 97.67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 67.77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 87.77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 77.7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 57.47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 47.37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 37.27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 27.17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 17.7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 7.38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 68.78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 28.98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 78.58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 98.8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 88.8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 8.58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 58.38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 38.99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 89.29.9.79.49.59.29.59.19.39.9.9.99.69.39 29.9.79.49.59.29.59.19.39.9.9.99.69.39 9.79.49.59.29.59.19.39.9.9.99.69.39 79.49.59.29.59.19.39.9.9.99.69.39 49.59.29.59.19.39.9.9.99.69.39 59.29.59.19.39.9.9.99.69.39 29.59.19.39.9.9.99.69.39 59.19.39.9.9.99.69.39 19.39.9.9.99.69.39 39.9.9.99.69.39 9.9.99.69.39 9.99.69.39 99.69.39 69.39 39 {} {} {} {}} + +do_execsql_test 1.17.14.6 { + SELECT group_concat(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t2 +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 1.17.15.1 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) +} {197 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 196 99.33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 195 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 194 33.89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 193 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 192 89.96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 191 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 190 96.38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 189 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 188 38.39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 187 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 186 39.91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 185 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 184 91.6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 183 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 182 6.97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 181 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 180 97.46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 179 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 178 46.54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 177 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 176 54.8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 175 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 174 8.29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 173 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 172 29.84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 171 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 170 84.23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 169 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 168 23.16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 167 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 166 16.65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 165 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 164 65.47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 163 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 162 47.86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 161 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 160 86.61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 159 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 158 61.85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 157 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 156 85.85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 155 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 154 85.59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 153 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 152 59.32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 151 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 150 32.3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 149 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 148 3.22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 147 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 146 22.55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 145 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 144 55.28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 143 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 142 28.25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 141 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 140 25.1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 139 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 138 1.40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 137 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 136 40.56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 135 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 134 56.75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 133 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 132 75.89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 131 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 130 89.76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 129 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 128 76.4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 127 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 126 4.42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 125 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 124 42.78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 123 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 122 78.29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 121 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 120 29.63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 119 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 118 63.87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 117 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 116 87.80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 115 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 114 80.72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 113 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 112 72.9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 111 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 110 9.73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 109 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 108 73.65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 107 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 106 65.58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 105 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 104 58.98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 103 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 102 98.21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 101 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 100 21.65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 99 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 98 65.5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 97 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 96 5.11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 95 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 94 11.87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 93 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 92 87.12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 91 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 90 12.20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 89 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 88 20.31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 87 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 86 31.95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 85 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 84 95.73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 83 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 82 73.88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 81 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 80 88.8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 79 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 78 8.49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 77 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 76 49.90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 75 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 74 90.96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 73 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 72 96.55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 71 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 70 55.77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 69 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 68 77.2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 67 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 66 2.85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 65 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 64 85.74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 63 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 62 74.70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 61 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 60 70.19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 59 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 58 19.26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 57 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 56 26.47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 55 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 54 47.90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 53 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 52 90.58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 51 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 50 58.9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 49 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 48 9.72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 47 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 46 72.33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 45 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 44 33.75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 43 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 42 75.81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 41 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 40 81.23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 39 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 38 23.13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 37 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 36 13.14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 35 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 34 14.91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 33 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 32 91.91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 31 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 30 91.15.36.3.69.52.50.10.33.39.58.38.83.82.7 29 15.36.3.69.52.50.10.33.39.58.38.83.82.7 28 15.36.3.69.52.50.10.33.39.58.38.83.82.7 27 36.3.69.52.50.10.33.39.58.38.83.82.7 26 36.3.69.52.50.10.33.39.58.38.83.82.7 25 3.69.52.50.10.33.39.58.38.83.82.7 24 3.69.52.50.10.33.39.58.38.83.82.7 23 69.52.50.10.33.39.58.38.83.82.7 22 69.52.50.10.33.39.58.38.83.82.7 21 52.50.10.33.39.58.38.83.82.7 20 52.50.10.33.39.58.38.83.82.7 19 50.10.33.39.58.38.83.82.7 18 50.10.33.39.58.38.83.82.7 17 10.33.39.58.38.83.82.7 16 10.33.39.58.38.83.82.7 15 33.39.58.38.83.82.7 14 33.39.58.38.83.82.7 13 39.58.38.83.82.7 12 39.58.38.83.82.7 11 58.38.83.82.7 10 58.38.83.82.7 9 38.83.82.7 8 38.83.82.7 7 83.82.7 6 83.82.7 5 82.7 4 82.7 3 7 2 7 1 {} 0 {} 0 {} 0 {} 0 {}} + +do_execsql_test 1.17.15.2 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 0=1) OVER win FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) +} {197 {} 196 {} 195 {} 194 {} 193 {} 192 {} 191 {} 190 {} 189 {} 188 {} 187 {} 186 {} 185 {} 184 {} 183 {} 182 {} 181 {} 180 {} 179 {} 178 {} 177 {} 176 {} 175 {} 174 {} 173 {} 172 {} 171 {} 170 {} 169 {} 168 {} 167 {} 166 {} 165 {} 164 {} 163 {} 162 {} 161 {} 160 {} 159 {} 158 {} 157 {} 156 {} 155 {} 154 {} 153 {} 152 {} 151 {} 150 {} 149 {} 148 {} 147 {} 146 {} 145 {} 144 {} 143 {} 142 {} 141 {} 140 {} 139 {} 138 {} 137 {} 136 {} 135 {} 134 {} 133 {} 132 {} 131 {} 130 {} 129 {} 128 {} 127 {} 126 {} 125 {} 124 {} 123 {} 122 {} 121 {} 120 {} 119 {} 118 {} 117 {} 116 {} 115 {} 114 {} 113 {} 112 {} 111 {} 110 {} 109 {} 108 {} 107 {} 106 {} 105 {} 104 {} 103 {} 102 {} 101 {} 100 {} 99 {} 98 {} 97 {} 96 {} 95 {} 94 {} 93 {} 92 {} 91 {} 90 {} 89 {} 88 {} 87 {} 86 {} 85 {} 84 {} 83 {} 82 {} 81 {} 80 {} 79 {} 78 {} 77 {} 76 {} 75 {} 74 {} 73 {} 72 {} 71 {} 70 {} 69 {} 68 {} 67 {} 66 {} 65 {} 64 {} 63 {} 62 {} 61 {} 60 {} 59 {} 58 {} 57 {} 56 {} 55 {} 54 {} 53 {} 52 {} 51 {} 50 {} 49 {} 48 {} 47 {} 46 {} 45 {} 44 {} 43 {} 42 {} 41 {} 40 {} 39 {} 38 {} 37 {} 36 {} 35 {} 34 {} 33 {} 32 {} 31 {} 30 {} 29 {} 28 {} 27 {} 26 {} 25 {} 24 {} 23 {} 22 {} 21 {} 20 {} 19 {} 18 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {}} + +do_execsql_test 1.17.15.3 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE 1=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) +} {16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {}} + +do_execsql_test 1.17.15.4 { + SELECT count(*) OVER win, group_concat(CAST(b AS TEXT), '.') + FILTER (WHERE a%2=0) OVER win FROM t2 + WINDOW win AS (PARTITION BY (a%10) ORDER BY a ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING) +} {16 59.28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 15 28.75.78.72.98.87.73.96.74.90.75.91.69.39.7 14 75.78.72.98.87.73.96.74.90.75.91.69.39.7 13 78.72.98.87.73.96.74.90.75.91.69.39.7 12 72.98.87.73.96.74.90.75.91.69.39.7 11 98.87.73.96.74.90.75.91.69.39.7 10 87.73.96.74.90.75.91.69.39.7 9 73.96.74.90.75.91.69.39.7 8 96.74.90.75.91.69.39.7 7 74.90.75.91.69.39.7 6 90.75.91.69.39.7 5 75.91.69.39.7 4 91.69.39.7 3 69.39.7 2 39.7 1 7 0 {} 0 {} 0 {} 0 {} 17 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 86.32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 15 32.25.89.29.9.21.12.88.55.70.58.81.91.52.58 14 25.89.29.9.21.12.88.55.70.58.81.91.52.58 13 89.29.9.21.12.88.55.70.58.81.91.52.58 12 29.9.21.12.88.55.70.58.81.91.52.58 11 9.21.12.88.55.70.58.81.91.52.58 10 21.12.88.55.70.58.81.91.52.58 9 12.88.55.70.58.81.91.52.58 8 88.55.70.58.81.91.52.58 7 55.70.58.81.91.52.58 6 70.58.81.91.52.58 5 58.81.91.52.58 4 81.91.52.58 3 91.52.58 2 52.58 1 58 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 61.3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 15 3.1.76.63.73.65.20.8.77.19.9.23.15.50.38 14 1.76.63.73.65.20.8.77.19.9.23.15.50.38 13 76.63.73.65.20.8.77.19.9.23.15.50.38 12 63.73.65.20.8.77.19.9.23.15.50.38 11 73.65.20.8.77.19.9.23.15.50.38 10 65.20.8.77.19.9.23.15.50.38 9 20.8.77.19.9.23.15.50.38 8 8.77.19.9.23.15.50.38 7 77.19.9.23.15.50.38 6 19.9.23.15.50.38 5 9.23.15.50.38 4 23.15.50.38 3 15.50.38 2 50.38 1 38 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 85.22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 15 22.40.4.87.65.5.31.49.2.26.72.13.36.10.83 14 40.4.87.65.5.31.49.2.26.72.13.36.10.83 13 4.87.65.5.31.49.2.26.72.13.36.10.83 12 87.65.5.31.49.2.26.72.13.36.10.83 11 65.5.31.49.2.26.72.13.36.10.83 10 5.31.49.2.26.72.13.36.10.83 9 31.49.2.26.72.13.36.10.83 8 49.2.26.72.13.36.10.83 7 2.26.72.13.36.10.83 6 26.72.13.36.10.83 5 72.13.36.10.83 4 13.36.10.83 3 36.10.83 2 10.83 1 83 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {} 16 85.55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 15 55.56.42.80.58.11.95.90.85.47.33.14.3.33.82 14 56.42.80.58.11.95.90.85.47.33.14.3.33.82 13 42.80.58.11.95.90.85.47.33.14.3.33.82 12 80.58.11.95.90.85.47.33.14.3.33.82 11 58.11.95.90.85.47.33.14.3.33.82 10 11.95.90.85.47.33.14.3.33.82 9 95.90.85.47.33.14.3.33.82 8 90.85.47.33.14.3.33.82 7 85.47.33.14.3.33.82 6 47.33.14.3.33.82 5 33.14.3.33.82 4 14.3.33.82 3 3.33.82 2 33.82 1 82 0 {} 0 {} 0 {} 0 {} 16 {} 15 {} 14 {} 13 {} 12 {} 11 {} 10 {} 9 {} 8 {} 7 {} 6 {} 5 {} 4 {} 3 {} 2 {} 1 {} 0 {} 0 {} 0 {} 0 {}} + +finish_test diff --git a/test/window4.tcl b/test/window4.tcl new file mode 100644 index 0000000000..33b3a8c0e8 --- /dev/null +++ b/test/window4.tcl @@ -0,0 +1,390 @@ +# 2018 May 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname $argv0] pg_common.tcl] + +#========================================================================= + +start_test window4 "2018 June 04" +ifcapable !windowfunc + +execsql_test 1.0 { + DROP TABLE IF EXISTS t3; + CREATE TABLE t3(a TEXT PRIMARY KEY); + INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e'); + INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j'); +} + +for {set i 1} {$i < 20} {incr i} { + execsql_test 1.$i "SELECT a, ntile($i) OVER (ORDER BY a) FROM t3" +} + +execsql_test 2.0 { + DROP TABLE IF EXISTS t4; + CREATE TABLE t4(a INTEGER PRIMARY KEY, b TEXT, c INTEGER); + INSERT INTO t4 VALUES(1, 'A', 9); + INSERT INTO t4 VALUES(2, 'B', 3); + INSERT INTO t4 VALUES(3, 'C', 2); + INSERT INTO t4 VALUES(4, 'D', 10); + INSERT INTO t4 VALUES(5, 'E', 5); + INSERT INTO t4 VALUES(6, 'F', 1); + INSERT INTO t4 VALUES(7, 'G', 1); + INSERT INTO t4 VALUES(8, 'H', 2); + INSERT INTO t4 VALUES(9, 'I', 10); + INSERT INTO t4 VALUES(10, 'J', 4); +} + +execsql_test 2.1 { + SELECT a, nth_value(b, c) OVER (ORDER BY a) FROM t4 +} + +execsql_test 2.2.1 { + SELECT a, lead(b) OVER (ORDER BY a) FROM t4 +} +execsql_test 2.2.2 { + SELECT a, lead(b, 2) OVER (ORDER BY a) FROM t4 +} +execsql_test 2.2.3 { + SELECT a, lead(b, 3, 'abc') OVER (ORDER BY a) FROM t4 +} + +execsql_test 2.3.1 { + SELECT a, lag(b) OVER (ORDER BY a) FROM t4 +} +execsql_test 2.3.2 { + SELECT a, lag(b, 2) OVER (ORDER BY a) FROM t4 +} +execsql_test 2.3.3 { + SELECT a, lag(b, 3, 'abc') OVER (ORDER BY a) FROM t4 +} + +execsql_test 2.4.1 { + SELECT string_agg(b, '.') OVER ( + ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t4 +} + +execsql_test 3.0 { + DROP TABLE IF EXISTS t5; + CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER); + INSERT INTO t5 VALUES(1, 'A', 'one', 5); + INSERT INTO t5 VALUES(2, 'B', 'two', 4); + INSERT INTO t5 VALUES(3, 'A', 'three', 3); + INSERT INTO t5 VALUES(4, 'B', 'four', 2); + INSERT INTO t5 VALUES(5, 'A', 'five', 1); +} + +execsql_test 3.1 { + SELECT a, nth_value(c, d) OVER (ORDER BY b) FROM t5 +} + +execsql_test 3.2 { + SELECT a, nth_value(c, d) OVER (PARTITION BY b ORDER BY a) FROM t5 +} + +execsql_test 3.3 { + SELECT a, count(*) OVER abc, count(*) OVER def FROM t5 + WINDOW abc AS (ORDER BY a), + def AS (ORDER BY a DESC) + ORDER BY a; +} + +execsql_test 3.4 { + SELECT a, max(a) FILTER (WHERE (a%2)=0) OVER w FROM t5 + WINDOW w AS (ORDER BY a) +} + +execsql_test 3.5.1 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING) + FROM t5 +} +execsql_test 3.5.2 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM t5 +} +execsql_test 3.5.3 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING) + FROM t5 +} + +execsql_test 3.6.1 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING) + FROM t5 +} +execsql_test 3.6.2 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) + FROM t5 +} +execsql_test 3.6.3 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING) + FROM t5 +} + +========== + +execsql_test 4.0 { + DROP TABLE IF EXISTS ttt; + CREATE TABLE ttt(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER); + INSERT INTO ttt VALUES(1, 1, 1); + INSERT INTO ttt VALUES(2, 2, 2); + INSERT INTO ttt VALUES(3, 3, 3); + + INSERT INTO ttt VALUES(4, 1, 2); + INSERT INTO ttt VALUES(5, 2, 3); + INSERT INTO ttt VALUES(6, 3, 4); + + INSERT INTO ttt VALUES(7, 1, 3); + INSERT INTO ttt VALUES(8, 2, 4); + INSERT INTO ttt VALUES(9, 3, 5); +} + +execsql_test 4.1 { + SELECT max(c), max(b) OVER (ORDER BY b) FROM ttt GROUP BY b; +} + +execsql_test 4.2 { + SELECT max(b) OVER (ORDER BY max(c)) FROM ttt GROUP BY b; +} + +execsql_test 4.3 { + SELECT abs(max(b) OVER (ORDER BY b)) FROM ttt GROUP BY b; +} + +execsql_test 4.4 { + SELECT sum(b) OVER ( + ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM ttt; +} + +set lPart [list "PARTITION BY b" "PARTITION BY b, a" "" "PARTITION BY a"] +set lOrder [list "ORDER BY a" "ORDER BY a DESC" "" "ORDER BY b, a"] +set lRange { + "RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" + "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING" + "RANGE BETWEEN CURRENT ROW AND CURRENT ROW" + "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" +} + +set lRows { + "ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING" + "ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING" + "ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING" + "ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING" + "ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING" +} + +set tn 1 +set SQL { + SELECT max(c) OVER ($p1 $o1 $r1), + min(c) OVER ($p2 $o2 $r2) + FROM ttt ORDER BY a +} +set SQL2 { + SELECT sum(c) OVER ($p1 $o1 $r1), + sum(c) OVER ($p2 $o2 $r2) + FROM ttt ORDER BY a +} + +set o1 [lindex $lOrder 0] +set o2 [lindex $lOrder 0] +set r1 [lindex $lRange 0] +set r2 [lindex $lRange 0] +foreach p1 $lPart { foreach p2 $lPart { + execsql_test 4.5.$tn.1 [subst $SQL] + execsql_test 4.5.$tn.2 [subst $SQL2] + incr tn +}} + +set o1 [lindex $lOrder 0] +set o2 [lindex $lOrder 0] +set p1 [lindex $lPart 0] +set p2 [lindex $lPart 0] +foreach r1 $lRange { foreach r2 $lRange { + execsql_test 4.5.$tn.1 [subst $SQL] + execsql_test 4.5.$tn.2 [subst $SQL2] + incr tn +}} +foreach r1 $lRows { foreach r2 $lRows { + execsql_test 4.5.$tn.1 [subst $SQL] + execsql_test 4.5.$tn.2 [subst $SQL2] + incr tn +}} + +set r1 [lindex $lRange 0] +set r2 [lindex $lRange 0] +set p1 [lindex $lPart 0] +set p2 [lindex $lPart 0] +foreach o1 $lOrder { foreach o2 $lOrder { + execsql_test 4.5.$tn.1 [subst $SQL] + execsql_test 4.5.$tn.2 [subst $SQL2] + incr tn +}} + +========== + +execsql_test 7.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x INTEGER, y INTEGER); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + INSERT INTO t1 VALUES(9, 10); +} + +execsql_test 7.1 { + SELECT lead(y) OVER win FROM t1 + WINDOW win AS (ORDER BY x) +} + +execsql_test 7.2 { + SELECT lead(y, 2) OVER win FROM t1 + WINDOW win AS (ORDER BY x) +} + +execsql_test 7.3 { + SELECT lead(y, 3, -1) OVER win FROM t1 + WINDOW win AS (ORDER BY x) +} + +execsql_test 7.4 { + SELECT + lead(y) OVER win, lead(y) OVER win + FROM t1 + WINDOW win AS (ORDER BY x) +} + +execsql_test 7.5 { + SELECT + lead(y) OVER win, + lead(y, 2) OVER win, + lead(y, 3, -1) OVER win + FROM t1 + WINDOW win AS (ORDER BY x) +} + +========== + +execsql_test 8.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER, d INTEGER); + INSERT INTO t1 VALUES(1, 2, 3, 4); + INSERT INTO t1 VALUES(5, 6, 7, 8); + INSERT INTO t1 VALUES(9, 10, 11, 12); +} + +execsql_test 8.1 { + SELECT row_number() OVER win, + nth_value(d,2) OVER win, + lead(d) OVER win + FROM t1 + WINDOW win AS (ORDER BY a) +} + +execsql_test 8.2 { + SELECT row_number() OVER win, + rank() OVER win, + dense_rank() OVER win, + ntile(2) OVER win, + first_value(d) OVER win, + last_value(d) OVER win, + nth_value(d,2) OVER win, + lead(d) OVER win, + lag(d) OVER win, + max(d) OVER win, + min(d) OVER win + FROM t1 + WINDOW win AS (ORDER BY a) +} + +========== + +execsql_test 9.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(x INTEGER); + INSERT INTO t2 VALUES(1), (1), (1), (4), (4), (6), (7); +} + +execsql_test 9.1 { + SELECT rank() OVER () FROM t2 +} +execsql_test 9.2 { + SELECT dense_rank() OVER (PARTITION BY x) FROM t2 +} +execsql_float_test 9.3 { + SELECT x, percent_rank() OVER (PARTITION BY x ORDER BY x) FROM t2 +} + +execsql_test 9.4 { + SELECT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2 +} + +execsql_test 9.5 { + SELECT DISTINCT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2 +} + +execsql_float_test 9.6 { + SELECT percent_rank() OVER () FROM t1 +} + +execsql_float_test 9.7 { + SELECT cume_dist() OVER () FROM t1 +} + +execsql_test 10.0 { + DROP TABLE IF EXISTS t7; + CREATE TABLE t7(id INTEGER PRIMARY KEY, a INTEGER, b INTEGER); + INSERT INTO t7(id, a, b) VALUES + (1, 1, 2), (2, 1, NULL), (3, 1, 4), + (4, 3, NULL), (5, 3, 8), (6, 3, 1); +} +execsql_test 10.1 { + SELECT id, min(b) OVER (PARTITION BY a ORDER BY id) FROM t7; +} + +execsql_test 10.2 { + SELECT id, lead(b, -1) OVER (PARTITION BY a ORDER BY id) FROM t7; +} +execsql_test 10.3 { + SELECT id, lag(b, -1) OVER (PARTITION BY a ORDER BY id) FROM t7; +} + +execsql_test 11.0 { + DROP VIEW IF EXISTS v8; + DROP TABLE IF EXISTS t8; + CREATE TABLE t8(t INT, total INT); + INSERT INTO t8 VALUES(0,2); + INSERT INTO t8 VALUES(5,1); + INSERT INTO t8 VALUES(10,1); +} + +execsql_test 11.1 { + SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8; +} + +execsql_test 11.2 { + CREATE VIEW v8 AS SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8; +} + +execsql_test 11.3 { + SELECT * FROM v8; +} + +execsql_test 11.4 { + SELECT * FROM ( + SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8 + ) sub; +} + + +finish_test + diff --git a/test/window4.test b/test/window4.test new file mode 100644 index 0000000000..e914c7826c --- /dev/null +++ b/test/window4.test @@ -0,0 +1,1320 @@ +# 2018 June 04 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +#################################################### +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! +#################################################### + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix window4 + +ifcapable !windowfunc { finish_test ; return } +do_execsql_test 1.0 { + DROP TABLE IF EXISTS t3; + CREATE TABLE t3(a TEXT PRIMARY KEY); + INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e'); + INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j'); +} {} + +do_execsql_test 1.1 { + SELECT a, ntile(1) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 1 d 1 e 1 f 1 g 1 h 1 i 1 j 1} + +do_execsql_test 1.2 { + SELECT a, ntile(2) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 1 d 1 e 1 f 2 g 2 h 2 i 2 j 2} + +do_execsql_test 1.3 { + SELECT a, ntile(3) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 1 d 1 e 2 f 2 g 2 h 3 i 3 j 3} + +do_execsql_test 1.4 { + SELECT a, ntile(4) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 1 d 2 e 2 f 2 g 3 h 3 i 4 j 4} + +do_execsql_test 1.5 { + SELECT a, ntile(5) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 2 d 2 e 3 f 3 g 4 h 4 i 5 j 5} + +do_execsql_test 1.6 { + SELECT a, ntile(6) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 2 d 2 e 3 f 3 g 4 h 4 i 5 j 6} + +do_execsql_test 1.7 { + SELECT a, ntile(7) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 2 d 2 e 3 f 3 g 4 h 5 i 6 j 7} + +do_execsql_test 1.8 { + SELECT a, ntile(8) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 2 d 2 e 3 f 4 g 5 h 6 i 7 j 8} + +do_execsql_test 1.9 { + SELECT a, ntile(9) OVER (ORDER BY a) FROM t3 +} {a 1 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9} + +do_execsql_test 1.10 { + SELECT a, ntile(10) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.11 { + SELECT a, ntile(11) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.12 { + SELECT a, ntile(12) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.13 { + SELECT a, ntile(13) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.14 { + SELECT a, ntile(14) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.15 { + SELECT a, ntile(15) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.16 { + SELECT a, ntile(16) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.17 { + SELECT a, ntile(17) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.18 { + SELECT a, ntile(18) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 1.19 { + SELECT a, ntile(19) OVER (ORDER BY a) FROM t3 +} {a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10} + +do_execsql_test 2.0 { + DROP TABLE IF EXISTS t4; + CREATE TABLE t4(a INTEGER PRIMARY KEY, b TEXT, c INTEGER); + INSERT INTO t4 VALUES(1, 'A', 9); + INSERT INTO t4 VALUES(2, 'B', 3); + INSERT INTO t4 VALUES(3, 'C', 2); + INSERT INTO t4 VALUES(4, 'D', 10); + INSERT INTO t4 VALUES(5, 'E', 5); + INSERT INTO t4 VALUES(6, 'F', 1); + INSERT INTO t4 VALUES(7, 'G', 1); + INSERT INTO t4 VALUES(8, 'H', 2); + INSERT INTO t4 VALUES(9, 'I', 10); + INSERT INTO t4 VALUES(10, 'J', 4); +} {} + +do_execsql_test 2.1 { + SELECT a, nth_value(b, c) OVER (ORDER BY a) FROM t4 +} {1 {} 2 {} 3 B 4 {} 5 E 6 A 7 A 8 B 9 {} 10 D} + +do_execsql_test 2.2.1 { + SELECT a, lead(b) OVER (ORDER BY a) FROM t4 +} {1 B 2 C 3 D 4 E 5 F 6 G 7 H 8 I 9 J 10 {}} + +do_execsql_test 2.2.2 { + SELECT a, lead(b, 2) OVER (ORDER BY a) FROM t4 +} {1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 {} 10 {}} + +do_execsql_test 2.2.3 { + SELECT a, lead(b, 3, 'abc') OVER (ORDER BY a) FROM t4 +} {1 D 2 E 3 F 4 G 5 H 6 I 7 J 8 abc 9 abc 10 abc} + +do_execsql_test 2.3.1 { + SELECT a, lag(b) OVER (ORDER BY a) FROM t4 +} {1 {} 2 A 3 B 4 C 5 D 6 E 7 F 8 G 9 H 10 I} + +do_execsql_test 2.3.2 { + SELECT a, lag(b, 2) OVER (ORDER BY a) FROM t4 +} {1 {} 2 {} 3 A 4 B 5 C 6 D 7 E 8 F 9 G 10 H} + +do_execsql_test 2.3.3 { + SELECT a, lag(b, 3, 'abc') OVER (ORDER BY a) FROM t4 +} {1 abc 2 abc 3 abc 4 A 5 B 6 C 7 D 8 E 9 F 10 G} + +do_execsql_test 2.4.1 { + SELECT group_concat(b, '.') OVER ( + ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM t4 +} {A.B.C.D.E.F.G.H.I.J B.C.D.E.F.G.H.I.J C.D.E.F.G.H.I.J D.E.F.G.H.I.J E.F.G.H.I.J F.G.H.I.J G.H.I.J H.I.J I.J J} + +do_execsql_test 3.0 { + DROP TABLE IF EXISTS t5; + CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER); + INSERT INTO t5 VALUES(1, 'A', 'one', 5); + INSERT INTO t5 VALUES(2, 'B', 'two', 4); + INSERT INTO t5 VALUES(3, 'A', 'three', 3); + INSERT INTO t5 VALUES(4, 'B', 'four', 2); + INSERT INTO t5 VALUES(5, 'A', 'five', 1); +} {} + +do_execsql_test 3.1 { + SELECT a, nth_value(c, d) OVER (ORDER BY b) FROM t5 +} {1 {} 3 five 5 one 2 two 4 three} + +do_execsql_test 3.2 { + SELECT a, nth_value(c, d) OVER (PARTITION BY b ORDER BY a) FROM t5 +} {1 {} 3 {} 5 one 2 {} 4 four} + +do_execsql_test 3.3 { + SELECT a, count(*) OVER abc, count(*) OVER def FROM t5 + WINDOW abc AS (ORDER BY a), + def AS (ORDER BY a DESC) + ORDER BY a; +} {1 1 5 2 2 4 3 3 3 4 4 2 5 5 1} + +do_execsql_test 3.4 { + SELECT a, max(a) FILTER (WHERE (a%2)=0) OVER w FROM t5 + WINDOW w AS (ORDER BY a) +} {1 {} 2 2 3 2 4 4 5 4} + +do_execsql_test 3.5.1 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING) + FROM t5 +} {1 {} 2 {} 3 {} 4 {} 5 {}} + +do_execsql_test 3.5.2 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM t5 +} {1 {} 2 one 3 two 4 three 5 four} + +do_execsql_test 3.5.3 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING) + FROM t5 +} {1 one 2 two 3 three 4 four 5 five} + +do_execsql_test 3.6.1 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING) + FROM t5 +} {1 {} 2 {} 3 {} 4 {} 5 {}} + +do_execsql_test 3.6.2 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) + FROM t5 +} {1 two 2 three 3 four 4 five 5 {}} + +do_execsql_test 3.6.3 { + SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING) + FROM t5 +} {1 one 2 two 3 three 4 four 5 five} + +#========================================================================== + +do_execsql_test 4.0 { + DROP TABLE IF EXISTS ttt; + CREATE TABLE ttt(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER); + INSERT INTO ttt VALUES(1, 1, 1); + INSERT INTO ttt VALUES(2, 2, 2); + INSERT INTO ttt VALUES(3, 3, 3); + + INSERT INTO ttt VALUES(4, 1, 2); + INSERT INTO ttt VALUES(5, 2, 3); + INSERT INTO ttt VALUES(6, 3, 4); + + INSERT INTO ttt VALUES(7, 1, 3); + INSERT INTO ttt VALUES(8, 2, 4); + INSERT INTO ttt VALUES(9, 3, 5); +} {} + +do_execsql_test 4.1 { + SELECT max(c), max(b) OVER (ORDER BY b) FROM ttt GROUP BY b; +} {3 1 4 2 5 3} + +do_execsql_test 4.2 { + SELECT max(b) OVER (ORDER BY max(c)) FROM ttt GROUP BY b; +} {1 2 3} + +do_execsql_test 4.3 { + SELECT abs(max(b) OVER (ORDER BY b)) FROM ttt GROUP BY b; +} {1 2 3} + +do_execsql_test 4.4 { + SELECT sum(b) OVER ( + ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ) FROM ttt; +} {18 17 15 12 11 9 6 5 3} + +do_execsql_test 4.5.1.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.1.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 3 5 5 7 7 6 6 9 9 12 12} + +do_execsql_test 4.5.2.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.2.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 2 5 3 7 4 6 3 9 4 12 5} + +do_execsql_test 4.5.3.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 1 3 1 2 1 3 1 4 1 3 1 4 1 5 1} + +do_execsql_test 4.5.3.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 3 3 6 3 8 5 11 7 15 6 18 9 22 12 27} + +do_execsql_test 4.5.4.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.4.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 2 5 3 7 4 6 3 9 4 12 5} + +do_execsql_test 4.5.5.1 { + SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.5.2 { + SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 3 3 5 4 7 3 6 4 9 5 12} + +do_execsql_test 4.5.6.1 { + SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.6.2 { + SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.7.1 { + SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 1 3 1 2 1 3 1 4 1 3 1 4 1 5 1} + +do_execsql_test 4.5.7.2 { + SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 3 3 6 2 8 3 11 4 15 3 18 4 22 5 27} + +do_execsql_test 4.5.8.1 { + SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.8.2 { + SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.9.1 { + SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 1 3 2 4 3 4 1 4 2 5 3} + +do_execsql_test 4.5.9.2 { + SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 3 2 6 3 8 3 11 5 15 7 18 6 22 9 27 12} + +do_execsql_test 4.5.10.1 { + SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 2 3 3 4 4 4 3 4 4 5 5} + +do_execsql_test 4.5.10.2 { + SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 3 2 6 3 8 2 11 3 15 4 18 3 22 4 27 5} + +do_execsql_test 4.5.11.1 { + SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 1 3 1 3 1 3 1 4 1 4 1 4 1 5 1} + +do_execsql_test 4.5.11.2 { + SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 3 3 6 6 8 8 11 11 15 15 18 18 22 22 27 27} + +do_execsql_test 4.5.12.1 { + SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 2 3 3 4 4 4 3 4 4 5 5} + +do_execsql_test 4.5.12.2 { + SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 3 2 6 3 8 2 11 3 15 4 18 3 22 4 27 5} + +do_execsql_test 4.5.13.1 { + SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.13.2 { + SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 3 3 5 4 7 3 6 4 9 5 12} + +do_execsql_test 4.5.14.1 { + SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.14.2 { + SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.15.1 { + SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 1 3 1 2 1 3 1 4 1 3 1 4 1 5 1} + +do_execsql_test 4.5.15.2 { + SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 3 3 6 2 8 3 11 4 15 3 18 4 22 5 27} + +do_execsql_test 4.5.16.1 { + SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.16.2 { + SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.17.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.17.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 3 5 5 7 7 6 6 9 9 12 12} + +do_execsql_test 4.5.18.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.18.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 3 6 5 9 7 12 6 6 9 9 12 12} + +do_execsql_test 4.5.19.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.19.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 2 5 3 7 4 6 3 9 4 12 5} + +do_execsql_test 4.5.20.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.20.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 3 5 5 7 7 9 6 3 9 4 12 5} + +do_execsql_test 4.5.21.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.21.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 6 3 9 5 12 7 6 6 9 9 12 12} + +do_execsql_test 4.5.22.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.22.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 6 6 9 9 12 12 6 6 9 9 12 12} + +do_execsql_test 4.5.23.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 2 4 3 5 4 3 3 4 4 5 5} + +do_execsql_test 4.5.23.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 6 2 9 3 12 4 6 3 9 4 12 5} + +do_execsql_test 4.5.24.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 2 4 3 5 4 3 3 4 4 5 5} + +do_execsql_test 4.5.24.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 6 5 9 7 12 9 6 3 9 4 12 5} + +do_execsql_test 4.5.25.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.25.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 3 3 5 4 7 3 6 4 9 5 12} + +do_execsql_test 4.5.26.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.26.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 2 6 3 9 4 12 3 6 4 9 5 12} + +do_execsql_test 4.5.27.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.27.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.28.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.28.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 2 5 3 7 4 9 3 3 4 4 5 5} + +do_execsql_test 4.5.29.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.29.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 5 3 7 5 9 7 3 6 4 9 5 12} + +do_execsql_test 4.5.30.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.30.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 5 6 7 9 9 12 3 6 4 9 5 12} + +do_execsql_test 4.5.31.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 2 4 3 5 4 3 3 4 4 5 5} + +do_execsql_test 4.5.31.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 5 2 7 3 9 4 3 3 4 4 5 5} + +do_execsql_test 4.5.32.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 2 4 3 5 4 3 3 4 4 5 5} + +do_execsql_test 4.5.32.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 5 5 7 7 9 9 3 3 4 4 5 5} + +do_execsql_test 4.5.33.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {2 1 3 2 4 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.33.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {3 3 5 5 7 7 6 6 9 9 12 12 6 6 9 9 12 12} + +do_execsql_test 4.5.34.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {2 1 3 2 4 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.34.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {3 6 5 9 7 12 6 6 9 9 12 12 6 6 9 9 12 12} + +do_execsql_test 4.5.35.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {2 {} 3 {} 4 {} 3 1 4 2 5 3 3 2 4 3 5 4} + +do_execsql_test 4.5.35.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {3 {} 5 {} 7 {} 6 1 9 2 12 3 6 2 9 3 12 4} + +do_execsql_test 4.5.36.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {2 {} 3 {} 4 {} 3 {} 4 {} 5 {} 3 {} 4 {} 5 {}} + +do_execsql_test 4.5.36.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {3 {} 5 {} 7 {} 6 {} 9 {} 12 {} 6 {} 9 {} 12 {}} + +do_execsql_test 4.5.37.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {2 2 3 3 4 4 3 3 4 4 5 5 3 {} 4 {} 5 {}} + +do_execsql_test 4.5.37.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {3 5 5 7 7 9 6 3 9 4 12 5 6 {} 9 {} 12 {}} + +do_execsql_test 4.5.38.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.38.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {6 3 9 5 12 7 6 6 9 9 12 12 6 6 9 9 12 12} + +do_execsql_test 4.5.39.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.39.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 6 6 9 9 12 12 6 6 9 9 12 12} + +do_execsql_test 4.5.40.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {3 {} 4 {} 5 {} 3 1 4 2 5 3 3 2 4 3 5 4} + +do_execsql_test 4.5.40.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {6 {} 9 {} 12 {} 6 1 9 2 12 3 6 2 9 3 12 4} + +do_execsql_test 4.5.41.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {3 {} 4 {} 5 {} 3 {} 4 {} 5 {} 3 {} 4 {} 5 {}} + +do_execsql_test 4.5.41.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {6 {} 9 {} 12 {} 6 {} 9 {} 12 {} 6 {} 9 {} 12 {}} + +do_execsql_test 4.5.42.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {3 2 4 3 5 4 3 3 4 4 5 5 3 {} 4 {} 5 {}} + +do_execsql_test 4.5.42.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {6 5 9 7 12 9 6 3 9 4 12 5 6 {} 9 {} 12 {}} + +do_execsql_test 4.5.43.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {{} 1 {} 2 {} 3 1 1 2 2 3 3 2 1 3 2 4 3} + +do_execsql_test 4.5.43.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {{} 3 {} 5 {} 7 1 6 2 9 3 12 2 6 3 9 4 12} + +do_execsql_test 4.5.44.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {{} 1 {} 2 {} 3 1 1 2 2 3 3 2 1 3 2 4 3} + +do_execsql_test 4.5.44.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {{} 6 {} 9 {} 12 1 6 2 9 3 12 2 6 3 9 4 12} + +do_execsql_test 4.5.45.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} 1 1 2 2 3 3 2 2 3 3 4 4} + +do_execsql_test 4.5.45.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} 1 1 2 2 3 3 2 2 3 3 4 4} + +do_execsql_test 4.5.46.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} 1 {} 2 {} 3 {} 2 {} 3 {} 4 {}} + +do_execsql_test 4.5.46.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} 1 {} 2 {} 3 {} 2 {} 3 {} 4 {}} + +do_execsql_test 4.5.47.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {{} 2 {} 3 {} 4 1 3 2 4 3 5 2 {} 3 {} 4 {}} + +do_execsql_test 4.5.47.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {{} 5 {} 7 {} 9 1 3 2 4 3 5 2 {} 3 {} 4 {}} + +do_execsql_test 4.5.48.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {{} 1 {} 2 {} 3 {} 1 {} 2 {} 3 {} 1 {} 2 {} 3} + +do_execsql_test 4.5.48.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {{} 3 {} 5 {} 7 {} 6 {} 9 {} 12 {} 6 {} 9 {} 12} + +do_execsql_test 4.5.49.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {{} 1 {} 2 {} 3 {} 1 {} 2 {} 3 {} 1 {} 2 {} 3} + +do_execsql_test 4.5.49.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {{} 6 {} 9 {} 12 {} 6 {} 9 {} 12 {} 6 {} 9 {} 12} + +do_execsql_test 4.5.50.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} {} 1 {} 2 {} 3 {} 2 {} 3 {} 4} + +do_execsql_test 4.5.50.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} {} 1 {} 2 {} 3 {} 2 {} 3 {} 4} + +do_execsql_test 4.5.51.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 4.5.51.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} + +do_execsql_test 4.5.52.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {{} 2 {} 3 {} 4 {} 3 {} 4 {} 5 {} {} {} {} {} {}} + +do_execsql_test 4.5.52.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {{} 5 {} 7 {} 9 {} 3 {} 4 {} 5 {} {} {} {} {} {}} + +do_execsql_test 4.5.53.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 {} 1 {} 2 {} 3} + +do_execsql_test 4.5.53.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) + FROM ttt ORDER BY a +} {5 3 7 5 9 7 3 6 4 9 5 12 {} 6 {} 9 {} 12} + +do_execsql_test 4.5.54.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 {} 1 {} 2 {} 3} + +do_execsql_test 4.5.54.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING) + FROM ttt ORDER BY a +} {5 6 7 9 9 12 3 6 4 9 5 12 {} 6 {} 9 {} 12} + +do_execsql_test 4.5.55.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {3 {} 4 {} 5 {} 3 1 4 2 5 3 {} 2 {} 3 {} 4} + +do_execsql_test 4.5.55.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {5 {} 7 {} 9 {} 3 1 4 2 5 3 {} 2 {} 3 {} 4} + +do_execsql_test 4.5.56.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {3 {} 4 {} 5 {} 3 {} 4 {} 5 {} {} {} {} {} {} {}} + +do_execsql_test 4.5.56.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING) + FROM ttt ORDER BY a +} {5 {} 7 {} 9 {} 3 {} 4 {} 5 {} {} {} {} {} {} {}} + +do_execsql_test 4.5.57.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {3 2 4 3 5 4 3 3 4 4 5 5 {} {} {} {} {} {}} + +do_execsql_test 4.5.57.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), + sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING) + FROM ttt ORDER BY a +} {5 5 7 7 9 9 3 3 4 4 5 5 {} {} {} {} {} {}} + +do_execsql_test 4.5.58.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.58.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 3 5 5 7 7 6 6 9 9 12 12} + +do_execsql_test 4.5.59.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.59.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 3 5 5 7 7 9 6 3 9 4 12 5} + +do_execsql_test 4.5.60.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.60.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 3 6 5 9 7 12 6 6 9 9 12 12} + +do_execsql_test 4.5.61.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.61.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 3 5 5 7 7 6 6 9 9 12 12} + +do_execsql_test 4.5.62.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.62.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 5 3 7 5 9 7 3 6 4 9 5 12} + +do_execsql_test 4.5.63.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 2 4 3 5 4 3 3 4 4 5 5} + +do_execsql_test 4.5.63.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 5 5 7 7 9 9 3 3 4 4 5 5} + +do_execsql_test 4.5.64.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.64.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 5 6 7 9 9 12 3 6 4 9 5 12} + +do_execsql_test 4.5.65.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.65.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 5 3 7 5 9 7 3 6 4 9 5 12} + +do_execsql_test 4.5.66.1 { + SELECT max(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.66.2 { + SELECT sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 6 3 9 5 12 7 6 6 9 9 12 12} + +do_execsql_test 4.5.67.1 { + SELECT max(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 2 4 3 5 4 3 3 4 4 5 5} + +do_execsql_test 4.5.67.2 { + SELECT sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 6 5 9 7 12 9 6 3 9 4 12 5} + +do_execsql_test 4.5.68.1 { + SELECT max(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.68.2 { + SELECT sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 6 9 9 12 12 6 6 9 9 12 12 6 6 9 9 12 12} + +do_execsql_test 4.5.69.1 { + SELECT max(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {3 1 4 2 5 3 3 1 4 2 5 3 3 1 4 2 5 3} + +do_execsql_test 4.5.69.2 { + SELECT sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {6 1 9 2 12 3 6 3 9 5 12 7 6 6 9 9 12 12} + +do_execsql_test 4.5.70.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.70.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 3 5 5 7 7 6 6 9 9 12 12} + +do_execsql_test 4.5.71.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 2 3 3 4 4 3 3 4 4 5 5} + +do_execsql_test 4.5.71.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 3 5 5 7 7 9 6 3 9 4 12 5} + +do_execsql_test 4.5.72.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.72.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 6 2 9 3 12 3 6 5 9 7 12 6 6 9 9 12 12} + +do_execsql_test 4.5.73.1 { + SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 2 1 3 2 4 3 3 1 4 2 5 3} + +do_execsql_test 4.5.73.2 { + SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + FROM ttt ORDER BY a +} {1 1 2 2 3 3 3 3 5 5 7 7 6 6 9 9 12 12} + +#========================================================================== + +do_execsql_test 7.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x INTEGER, y INTEGER); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + INSERT INTO t1 VALUES(9, 10); +} {} + +do_execsql_test 7.1 { + SELECT lead(y) OVER win FROM t1 + WINDOW win AS (ORDER BY x) +} {4 6 8 10 {}} + +do_execsql_test 7.2 { + SELECT lead(y, 2) OVER win FROM t1 + WINDOW win AS (ORDER BY x) +} {6 8 10 {} {}} + +do_execsql_test 7.3 { + SELECT lead(y, 3, -1) OVER win FROM t1 + WINDOW win AS (ORDER BY x) +} {8 10 -1 -1 -1} + +do_execsql_test 7.4 { + SELECT + lead(y) OVER win, lead(y) OVER win + FROM t1 + WINDOW win AS (ORDER BY x) +} {4 4 6 6 8 8 10 10 {} {}} + +do_execsql_test 7.5 { + SELECT + lead(y) OVER win, + lead(y, 2) OVER win, + lead(y, 3, -1) OVER win + FROM t1 + WINDOW win AS (ORDER BY x) +} {4 6 8 6 8 10 8 10 -1 10 {} -1 {} {} -1} + +#========================================================================== + +do_execsql_test 8.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER, d INTEGER); + INSERT INTO t1 VALUES(1, 2, 3, 4); + INSERT INTO t1 VALUES(5, 6, 7, 8); + INSERT INTO t1 VALUES(9, 10, 11, 12); +} {} + +do_execsql_test 8.1 { + SELECT row_number() OVER win, + nth_value(d,2) OVER win, + lead(d) OVER win + FROM t1 + WINDOW win AS (ORDER BY a) +} {1 {} 8 2 8 12 3 8 {}} + +do_execsql_test 8.2 { + SELECT row_number() OVER win, + rank() OVER win, + dense_rank() OVER win, + ntile(2) OVER win, + first_value(d) OVER win, + last_value(d) OVER win, + nth_value(d,2) OVER win, + lead(d) OVER win, + lag(d) OVER win, + max(d) OVER win, + min(d) OVER win + FROM t1 + WINDOW win AS (ORDER BY a) +} {1 1 1 1 4 4 {} 8 {} 4 4 2 2 2 1 4 8 8 12 4 8 4 3 3 3 2 4 12 8 {} 8 12 4} + +#========================================================================== + +do_execsql_test 9.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(x INTEGER); + INSERT INTO t2 VALUES(1), (1), (1), (4), (4), (6), (7); +} {} + +do_execsql_test 9.1 { + SELECT rank() OVER () FROM t2 +} {1 1 1 1 1 1 1} + +do_execsql_test 9.2 { + SELECT dense_rank() OVER (PARTITION BY x) FROM t2 +} {1 1 1 1 1 1 1} + + +do_test 9.3 { + set myres {} + foreach r [db eval {SELECT x, percent_rank() OVER (PARTITION BY x ORDER BY x) FROM t2}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 0.0000 1.0000 0.0000 1.0000 0.0000 4.0000 0.0000 4.0000 0.0000 6.0000 0.0000 7.0000 0.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 9.4 { + SELECT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2 +} {1 1 1 1 1 1 4 4 4 4 6 6 7 7} + +do_execsql_test 9.5 { + SELECT DISTINCT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2 +} {1 1 4 4 6 6 7 7} + + +do_test 9.6 { + set myres {} + foreach r [db eval {SELECT percent_rank() OVER () FROM t1}] { + lappend myres [format %.4f [set r]] + } + set res2 {0.0000 0.0000 0.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + + +do_test 9.7 { + set myres {} + foreach r [db eval {SELECT cume_dist() OVER () FROM t1}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000} + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + } + set {} {} +} {} + +do_execsql_test 10.0 { + DROP TABLE IF EXISTS t7; + CREATE TABLE t7(id INTEGER PRIMARY KEY, a INTEGER, b INTEGER); + INSERT INTO t7(id, a, b) VALUES + (1, 1, 2), (2, 1, NULL), (3, 1, 4), + (4, 3, NULL), (5, 3, 8), (6, 3, 1); +} {} + +do_execsql_test 10.1 { + SELECT id, min(b) OVER (PARTITION BY a ORDER BY id) FROM t7; +} {1 2 2 2 3 2 4 {} 5 8 6 1} + +do_execsql_test 10.2 { + SELECT id, lead(b, -1) OVER (PARTITION BY a ORDER BY id) FROM t7; +} {1 {} 2 2 3 {} 4 {} 5 {} 6 8} + +do_execsql_test 10.3 { + SELECT id, lag(b, -1) OVER (PARTITION BY a ORDER BY id) FROM t7; +} {1 {} 2 4 3 {} 4 8 5 1 6 {}} + +do_execsql_test 11.0 { + DROP VIEW IF EXISTS v8; + DROP TABLE IF EXISTS t8; + CREATE TABLE t8(t INT, total INT); + INSERT INTO t8 VALUES(0,2); + INSERT INTO t8 VALUES(5,1); + INSERT INTO t8 VALUES(10,1); +} {} + +do_execsql_test 11.1 { + SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8; +} {0 1 2} + +do_execsql_test 11.2 { + CREATE VIEW v8 AS SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8; +} {} + +do_execsql_test 11.3 { + SELECT * FROM v8; +} {0 1 2} + +do_execsql_test 11.4 { + SELECT * FROM ( + SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8 + ) sub; +} {0 1 2} + +finish_test diff --git a/test/window5.test b/test/window5.test new file mode 100644 index 0000000000..40d218f2ab --- /dev/null +++ b/test/window5.test @@ -0,0 +1,97 @@ +# 2018 May 8 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. Specifically, +# it tests the sqlite3_create_window_function() API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix window5 + +ifcapable !windowfunc { + finish_test + return +} + +proc m_step {ctx val} { + lappend ctx $val + return $ctx +} +proc m_value {ctx} { + set lSort [lsort $ctx] + + set nVal [llength $lSort] + set n [expr $nVal/2] + + if {($nVal % 2)==0 && $nVal>0} { + set a [lindex $lSort $n] + set b [lindex $lSort $n-1] + if {($a+$b) % 2} { + set ret [expr ($a+$b)/2.0] + } else { + set ret [expr ($a+$b)/2] + } + } else { + set ret [lindex $lSort $n] + } + return $ret +} +proc m_inverse {ctx val} { + set ctx [lrange $ctx 1 end] + return $ctx +} +proc w_value {ctx} { + lsort $ctx +} + +sqlite3_create_window_function db median m_step m_value m_value m_inverse +sqlite3_create_window_function db win m_step w_value w_value m_inverse + +do_test 0.0 { + test_create_window_function_misuse db +} {} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(4, 'a'); + INSERT INTO t1 VALUES(6, 'b'); + INSERT INTO t1 VALUES(1, 'c'); + INSERT INTO t1 VALUES(5, 'd'); + INSERT INTO t1 VALUES(2, 'e'); + INSERT INTO t1 VALUES(3, 'f'); +} + +do_execsql_test 1.1 { + SELECT win(a) OVER (ORDER BY b), median(a) OVER (ORDER BY b) FROM t1; +} {4 4 {4 6} 5 {1 4 6} 4 {1 4 5 6} 4.5 {1 2 4 5 6} 4 {1 2 3 4 5 6} 3.5} + +test_create_sumint db +do_execsql_test 2.0 { + SELECT sumint(a) OVER (ORDER BY rowid) FROM t1 ORDER BY rowid; +} {4 10 11 16 18 21} + +do_execsql_test 2.1 { + SELECT sumint(a) OVER (ORDER BY rowid ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t1 ORDER BY rowid; +} {10 11 12 8 10 5} + +test_override_sum db +do_catchsql_test 3.0 { + SELECT sum(a) OVER + (ORDER BY b ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) + FROM t1; +} {1 {sum() may not be used as a window function}} +do_execsql_test 3.1 { + SELECT sum(a) FROM t1; +} {21} + + +finish_test + diff --git a/test/window6.test b/test/window6.test new file mode 100644 index 0000000000..06cebcf1a8 --- /dev/null +++ b/test/window6.test @@ -0,0 +1,340 @@ +# 2018 May 8 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. Specifically, +# it tests the sqlite3_create_window_function() API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix window6 + +ifcapable !windowfunc { + finish_test + return +} + +set setup { + CREATE TABLE %t1(%x, %y %typename); + INSERT INTO %t1 VALUES(1, 'a'); + INSERT INTO %t1 VALUES(2, 'b'); + INSERT INTO %t1 VALUES(3, 'c'); + INSERT INTO %t1 VALUES(4, 'd'); + INSERT INTO %t1 VALUES(5, 'e'); +} + +foreach {tn vars} { + 1 {} + 2 { set A(%t1) over } + 3 { set A(%x) over } + 4 { + set A(%alias) over + set A(%x) following + set A(%y) over + } + 5 { + set A(%t1) over + set A(%x) following + set A(%y) preceding + set A(%w) current + set A(%alias) filter + set A(%typename) window + } + + 6 { + set A(%x) window + } +} { + set A(%t1) t1 + set A(%x) x + set A(%y) y + set A(%w) w + set A(%alias) alias + set A(%typename) integer + eval $vars + + set MAP [array get A] + set setup_sql [string map $MAP $setup] + reset_db + execsql $setup_sql + + do_execsql_test 1.$tn.1 [string map $MAP { + SELECT group_concat(%x, '.') OVER (ORDER BY %y) FROM %t1 + }] {1 1.2 1.2.3 1.2.3.4 1.2.3.4.5} + + do_execsql_test 1.$tn.2 [string map $MAP { + SELECT sum(%x) OVER %w FROM %t1 WINDOW %w AS (ORDER BY %y) + }] {1 3 6 10 15} + + do_execsql_test 1.$tn.3 [string map $MAP { + SELECT sum(%alias.%x) OVER %w FROM %t1 %alias WINDOW %w AS (ORDER BY %y) + }] {1 3 6 10 15} + + do_execsql_test 1.$tn.4 [string map $MAP { + SELECT sum(%x) %alias FROM %t1 + }] {15} +} + + +proc winproc {args} { return "window: $args" } +db func window winproc +do_execsql_test 2.0 { + SELECT window('hello world'); +} {{window: {hello world}}} + +proc wincmp {a b} { string compare $b $a } +db collate window wincmp +do_execsql_test 3.0 { + CREATE TABLE window(x COLLATE window); + INSERT INTO window VALUES('bob'), ('alice'), ('cate'); + SELECT * FROM window ORDER BY x COLLATE window; +} {cate bob alice} +do_execsql_test 3.1 { + DROP TABLE window; + CREATE TABLE x1(x); + INSERT INTO x1 VALUES('bob'), ('alice'), ('cate'); + CREATE INDEX window ON x1(x COLLATE window); + SELECT * FROM x1 ORDER BY x COLLATE window; +} {cate bob alice} + + +do_execsql_test 4.0 { CREATE TABLE t4(x, y); } + +# do_execsql_test 4.1 { PRAGMA parser_trace = 1 } +do_execsql_test 4.1 { + SELECT * FROM t4 window, t4; +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 5.0 { + CREATE TABLE over(x, over); + CREATE TABLE window(x, window); + INSERT INTO over VALUES(1, 2), (3, 4), (5, 6); + INSERT INTO window VALUES(1, 2), (3, 4), (5, 6); + SELECT sum(x) over FROM over +} {9} + +do_execsql_test 5.1 { + SELECT sum(x) over over FROM over WINDOW over AS () +} {9 9 9} + +do_execsql_test 5.2 { + SELECT sum(over) over over over FROM over over WINDOW over AS (ORDER BY over) +} {2 6 12} + +do_execsql_test 5.3 { + SELECT sum(over) over over over FROM over over WINDOW over AS (ORDER BY over); +} {2 6 12} + +do_execsql_test 5.4 { + SELECT sum(window) OVER window window FROM window window window window AS (ORDER BY window); +} {2 6 12} + +do_execsql_test 5.5 { + SELECT count(*) OVER win FROM over + WINDOW win AS (ORDER BY x ROWS BETWEEN +2 FOLLOWING AND +3 FOLLOWING) +} {1 0 0} + +#------------------------------------------------------------------------- +# + +ifcapable !icu { + do_execsql_test 6.0 { + SELECT LIKE('!', '', '!') x WHERE x; + } {} + do_execsql_test 6.1 { + SELECT LIKE("!","","!")""WHeRE""; + } {} + do_catchsql_test 6.2 { + SELECT LIKE("!","","!")""window""; + } {1 {near "window": syntax error}} +} + +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(x TEXT); + CREATE INDEX i1 ON t1(x COLLATE nocase); + INSERT INTO t1 VALUES(''); +} + +ifcapable !icu { + do_execsql_test 7.1 { + SELECT count(*) FROM t1 WHERE x LIKE '!' ESCAPE '!'; + } {0} +} + +#------------------------------------------------------------------------- +# +do_execsql_test 8.0 { + CREATE TABLE IF NOT EXISTS "sample" ( + "id" INTEGER NOT NULL PRIMARY KEY, + "counter" INTEGER NOT NULL, + "value" REAL NOT NULL + ); + + INSERT INTO "sample" (counter, value) + VALUES (1, 10.), (1, 20.), (2, 1.), (2, 3.), (3, 100.); +} + +do_execsql_test 8.1 { + SELECT "counter", "value", RANK() OVER w AS "rank" + FROM "sample" + WINDOW w AS (PARTITION BY "counter" ORDER BY "value" DESC) + ORDER BY "counter", RANK() OVER w +} { + 1 20.0 1 1 10.0 2 2 3.0 1 2 1.0 2 3 100.0 1 +} + +do_execsql_test 8.2 { + SELECT "counter", "value", SUM("value") OVER + (ORDER BY "id" ROWS 2 PRECEDING) + FROM "sample" + ORDER BY "id" +} { + 1 10.0 10.0 1 20.0 30.0 2 1.0 31.0 2 3.0 24.0 3 100.0 104.0 +} + +do_execsql_test 8.3 { + SELECT SUM("value") OVER + (ORDER BY "id" ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) + FROM "sample" + ORDER BY "id" +} { + 10.0 30.0 31.0 24.0 104.0 +} + +do_execsql_test 9.0 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT x, group_concat(x) OVER (ORDER BY x ROWS 2 PRECEDING) + FROM c; +} { + 1 1 2 1,2 3 1,2,3 4 2,3,4 5 3,4,5 +} +do_catchsql_test 9.1 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT x, group_concat(x) OVER (ORDER BY x RANGE 2 PRECEDING) + FROM c; +} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}} + +do_catchsql_test 9.2 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT x, group_concat(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING) + FROM c; +} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}} + +do_catchsql_test 9.3 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT count(DISTINCT x) OVER (ORDER BY x) FROM c; +} {1 {DISTINCT is not supported for window functions}} + +do_catchsql_test 9.4 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT count() OVER (ORDER BY x RANGE UNBOUNDED FOLLOWING) FROM c; +} {1 {near "FOLLOWING": syntax error}} + +do_catchsql_test 9.5 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT count() OVER (ORDER BY x RANGE BETWEEN UNBOUNDED FOLLOWING AND UNBOUNDED FOLLOWING) FROM c; +} {1 {near "FOLLOWING": syntax error}} + +do_catchsql_test 9.6 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT count() OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED PRECEDING) FROM c; +} {1 {near "PRECEDING": syntax error}} + +foreach {tn frame} { + 1 "BETWEEN CURRENT ROW AND 4 PRECEDING" + 2 "4 FOLLOWING" + 3 "BETWEEN 4 FOLLOWING AND CURRENT ROW" + 4 "BETWEEN 4 FOLLOWING AND 2 PRECEDING" +} { + do_catchsql_test 9.7.$tn " + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT count() OVER ( + ORDER BY x ROWS $frame + ) FROM c; + " {1 {unsupported frame delimiter for ROWS}} +} + +do_catchsql_test 9.8.1 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT count() OVER ( + ORDER BY x ROWS BETWEEN a PRECEDING AND 2 FOLLOWING + ) FROM c; +} {1 {frame starting offset must be a non-negative integer}} +do_catchsql_test 9.8.2 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5) + SELECT count() OVER ( + ORDER BY x ROWS BETWEEN 2 PRECEDING AND a FOLLOWING + ) FROM c; +} {1 {frame ending offset must be a non-negative integer}} + +do_execsql_test 10.0 { + WITH t1(a,b) AS (VALUES(1,2)) + SELECT count() FILTER (where b<>5) OVER w1 + FROM t1 + WINDOW w1 AS (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING); +} {1} + +foreach {tn stmt} { + 1 "SELECT nth_value(b, 0) OVER (ORDER BY a) FROM t1" + 2 "SELECT nth_value(b, -1) OVER (ORDER BY a) FROM t1" + 3 "SELECT nth_value(b, '4ab') OVER (ORDER BY a) FROM t1" + 4 "SELECT nth_value(b, NULL) OVER (ORDER BY a) FROM t1" + 5 "SELECT nth_value(b, 8.5) OVER (ORDER BY a) FROM t1" +} { + do_catchsql_test 10.1.$tn " + WITH t1(a,b) AS ( VALUES(1, 2), (2, 3), (3, 4) ) + $stmt + " {1 {second argument to nth_value must be a positive integer}} +} + +foreach {tn stmt res} { + 1 "SELECT nth_value(b, 1) OVER (ORDER BY a) FROM t1" {2 2 2} + 2 "SELECT nth_value(b, 2) OVER (ORDER BY a) FROM t1" {{} 3 3} + 3 "SELECT nth_value(b, '2') OVER (ORDER BY a) FROM t1" {{} 3 3} + 4 "SELECT nth_value(b, 2.0) OVER (ORDER BY a) FROM t1" {{} 3 3} + 5 "SELECT nth_value(b, '2.0') OVER (ORDER BY a) FROM t1" {{} 3 3} + 6 "SELECT nth_value(b, 10000000) OVER (ORDER BY a) FROM t1" {{} {} {}} +} { + do_execsql_test 10.2.$tn " + WITH t1(a,b) AS ( VALUES(1, 2), (2, 3), (3, 4) ) + $stmt + " $res +} + + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 11.0 { + CREATE TABLE t1(a INT); + INSERT INTO t1 VALUES(10),(15),(20),(20),(25),(30),(30),(50); + CREATE TABLE t3(x INT, y VARCHAR); + INSERT INTO t3(x,y) VALUES(10,'ten'),('15','fifteen'),(30,'thirty'); +} + +do_execsql_test 11.1 { + SELECT a, (SELECT y FROM t3 WHERE x=a) FROM t1 ORDER BY a; +} { + 10 ten 15 fifteen 20 {} 20 {} 25 {} 30 thirty 30 thirty 50 {} +} + +do_execsql_test 11.2 { + SELECT a, (SELECT y FROM t3 WHERE x=a), sum(a) OVER (ORDER BY a) + FROM t1 ORDER BY a; +} { + 10 ten 10 15 fifteen 25 20 {} 65 20 {} 65 + 25 {} 90 30 thirty 150 30 thirty 150 50 {} 200 +} + +finish_test diff --git a/test/windowfault.test b/test/windowfault.test new file mode 100644 index 0000000000..e08d994166 --- /dev/null +++ b/test/windowfault.test @@ -0,0 +1,166 @@ +# 2018 May 8 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix windowfault + +ifcapable !windowfunc { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c, d); + INSERT INTO t1 VALUES(1, 2, 3, 4); + INSERT INTO t1 VALUES(5, 6, 7, 8); + INSERT INTO t1 VALUES(9, 10, 11, 12); +} +faultsim_save_and_close + +do_faultsim_test 1 -start 1 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT row_number() OVER win, + rank() OVER win, + dense_rank() OVER win, + ntile(2) OVER win, + first_value(d) OVER win, + last_value(d) OVER win, + nth_value(d,2) OVER win, + lead(d) OVER win, + lag(d) OVER win, + max(d) OVER win, + min(d) OVER win + FROM t1 + WINDOW win AS (ORDER BY a) + } +} -test { + faultsim_test_result {0 {1 1 1 1 4 4 {} 8 {} 4 4 2 2 2 1 4 8 8 12 4 8 4 3 3 3 2 4 12 8 {} 8 12 4}} +} + +do_faultsim_test 1.1 -faults oom-t* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT row_number() OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t1 + WINDOW win AS (PARTITION BY c<7 ORDER BY a) + } +} -test { + faultsim_test_result {0 {1 1 1 2 2 2 1 1 1}} +} + +do_faultsim_test 1.2 -faults oom-t* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT ntile(105) + OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) + FROM t1 + } +} -test { + faultsim_test_result {0 {1 2 3}} +} + +do_faultsim_test 2 -start 1 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT round(percent_rank() OVER win, 2), + round(cume_dist() OVER win, 2) + FROM t1 + WINDOW win AS (ORDER BY a) + } +} -test { + faultsim_test_result {0 {0.0 0.33 0.5 0.67 1.0 1.0}} +} + +do_faultsim_test 3 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT min(d) OVER win, max(d) OVER win + FROM t1 + WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + } +} -test { + faultsim_test_result {0 {4 12 8 12 12 12}} +} + +do_faultsim_test 4 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + CREATE VIEW aaa AS + SELECT min(d) OVER w, max(d) OVER w + FROM t1 + WINDOW w AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING); + SELECT * FROM aaa; + } +} -test { + faultsim_test_result {0 {4 12 8 12 12 12}} +} + +do_faultsim_test 5 -start 1 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT last_value(a) OVER win1, + last_value(a) OVER win2 + FROM t1 + WINDOW win1 AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING), + win2 AS (ORDER BY a) + } +} -test { + faultsim_test_result {0 {5 1 9 5 9 9}} +} + +do_faultsim_test 6 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT percent_rank() OVER (), cume_dist() OVER () FROM t1 + } +} -test { + faultsim_test_result {0 {0.0 1.0 0.0 1.0 0.0 1.0}} +} + +do_faultsim_test 7 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT percent_rank() OVER (), cume_dist() OVER () FROM t1 + } +} -test { + faultsim_test_result {0 {0.0 1.0 0.0 1.0 0.0 1.0}} +} + +do_faultsim_test 8 -faults oom-t* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + SELECT a, sum(b) OVER win1 FROM t1 + WINDOW win1 AS (PARTITION BY a ), + win2 AS (PARTITION BY b ) + ORDER BY a; + } +} -test { + faultsim_test_result {0 {1 2 5 6 9 10}} +} + +finish_test + diff --git a/test/with1.test b/test/with1.test index 252a32bc69..f9b41ff615 100644 --- a/test/with1.test +++ b/test/with1.test @@ -865,6 +865,27 @@ do_catchsql_test 16.1 { SELECT * FROM i; } {1 {recursive aggregate queries not supported}} +# Or window-function recursive queries. Ticket e8275b41. +# +ifcapable windowfunc { + do_catchsql_test 16.2 { + WITH RECURSIVE + i(x) AS (VALUES(1) UNION SELECT count(*) OVER () FROM i) + SELECT * FROM i; + } {1 {cannot use window functions in recursive queries}} + do_catchsql_test 16.3 { + WITH RECURSIVE + t(id, parent) AS (VALUES(1,2)), + q(id, parent, rn) AS ( + VALUES(1,2,3) + UNION ALL + SELECT t.*, ROW_NUMBER() OVER (ORDER BY t.id) AS rn + FROM q JOIN t ON t.parent = q.id + ) + SELECT * FROM q; + } {1 {cannot use window functions in recursive queries}} +} + #------------------------------------------------------------------------- do_execsql_test 17.1 { WITH x(a) AS ( @@ -992,17 +1013,35 @@ do_execsql_test 18.2 { # EXPLAIN QUERY PLAN on a self-join of a CTE # -do_execsql_test 19.1 { +do_execsql_test 19.1a { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x); - EXPLAIN QUERY PLAN +} +do_eqp_test 19.1b { WITH x1(a) AS (values(100)) INSERT INTO t1(x) SELECT * FROM (WITH x2(y) AS (SELECT * FROM x1) SELECT y+a FROM x1, x2); SELECT * FROM t1; -} {0 0 0 {SCAN SUBQUERY 1} 0 1 1 {SCAN SUBQUERY 1}} - +} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | `--SCAN CONSTANT ROW + |--SCAN SUBQUERY xxxxxx + `--SCAN SUBQUERY xxxxxx +} +# 2017-10-28. +# See check-in https://sqlite.org/src/info/0926df095faf72c2 +# Tried to optimize co-routine processing by changing a Copy opcode +# into SCopy. But OSSFuzz found two (similar) cases where that optimization +# does not work. +# +do_execsql_test 20.1 { + WITH c(i)AS(VALUES(9)UNION SELECT~i FROM c)SELECT max(5)>i fROM c; +} {0} +do_execsql_test 20.2 { + WITH c(i)AS(VALUES(5)UNIoN SELECT 0)SELECT min(1)-i fROM c; +} {1} finish_test diff --git a/test/with2.test b/test/with2.test index 02d10b5112..004ec94b97 100644 --- a/test/with2.test +++ b/test/with2.test @@ -326,7 +326,7 @@ do_catchsql_test 6.5 { do_catchsql_test 6.6 { WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHERE -} {/1 {near .* syntax error}/} +} {1 {incomplete input}} do_catchsql_test 6.7 { WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHRE 1; diff --git a/test/with3.test b/test/with3.test index 5540a7fca6..de150b1fc1 100644 --- a/test/with3.test +++ b/test/with3.test @@ -79,22 +79,30 @@ ifcapable analyze { do_eqp_test 3.1.2 { WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1) SELECT * FROM cnt, y1 WHERE i=a - } { - 3 0 0 {SCAN TABLE cnt} - 1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} - 0 0 0 {SCAN SUBQUERY 1} - 0 1 1 {SEARCH TABLE y1 USING INDEX y1a (a=?)} - } + } [string map {"\n " \n} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--SETUP + | | `--SCAN CONSTANT ROW + | `--RECURSIVE STEP + | `--SCAN TABLE cnt + |--SCAN SUBQUERY xxxxxx + `--SEARCH TABLE y1 USING INDEX y1a (a=?) + }] do_eqp_test 3.1.3 { WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1000000) SELECT * FROM cnt, y1 WHERE i=a - } { - 3 0 0 {SCAN TABLE cnt} - 1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} - 0 0 1 {SCAN TABLE y1} - 0 1 0 {SEARCH SUBQUERY 1 USING AUTOMATIC COVERING INDEX (i=?)} - } + } [string map {"\n " \n} { + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--SETUP + | | `--SCAN CONSTANT ROW + | `--RECURSIVE STEP + | `--SCAN TABLE cnt + |--SCAN TABLE y1 + `--SEARCH SUBQUERY xxxxxx USING AUTOMATIC COVERING INDEX (i=?) + }] } do_execsql_test 3.2.1 { @@ -108,13 +116,18 @@ do_eqp_test 3.2.2 { SELECT * FROM c, w2, w1 WHERE c.id=w2.pk AND c.id=w1.pk; } { - 2 0 0 {EXECUTE SCALAR SUBQUERY 3} - 3 0 0 {SCAN TABLE w2} - 4 0 0 {SCAN TABLE w1} - 4 1 1 {SCAN TABLE c} - 1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} 0 0 0 {SCAN SUBQUERY 1} - 0 1 1 {SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)} - 0 2 2 {SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)} + QUERY PLAN + |--MATERIALIZE xxxxxx + | |--SETUP + | | |--SCAN CONSTANT ROW + | | `--SCALAR SUBQUERY + | | `--SCAN TABLE w2 + | `--RECURSIVE STEP + | |--SCAN TABLE w1 + | `--SCAN TABLE c + |--SCAN SUBQUERY xxxxxx + |--SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?) + `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?) } finish_test diff --git a/test/with4.test b/test/with4.test new file mode 100644 index 0000000000..b0eeba6d14 --- /dev/null +++ b/test/with4.test @@ -0,0 +1,52 @@ +# 2018-02-15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the WITH clause in TRIGGERs and VIEWs. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix with4 + +ifcapable {!cte} { + finish_test + return +} + +do_execsql_test 100 { + ATTACH ':memory:' AS aux; + CREATE TABLE main.t1(a,b); + CREATE TABLE aux.t2(x,y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(3,4); +} {} +do_catchsql_test 110 { + CREATE VIEW v1 AS SELECT * FROM t1, aux.t2; +} {1 {view v1 cannot reference objects in database aux}} +do_catchsql_test 120 { + CREATE VIEW v2 AS WITH v(m,n) AS (SELECT x,y FROM aux.t2) SELECT * FROM t1, v; +} {1 {view v2 cannot reference objects in database aux}} +do_catchsql_test 130 { + CREATE VIEW v2 AS WITH v(m,n) AS (SELECT 5,?2) SELECT * FROM t1, v; +} {1 {parameters are not allowed in views}} + +do_catchsql_test 200 { + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + WITH v(m,n) AS (SELECT x,y FROM aux.t2) SELECT * FROM t1, v; + END; +} {1 {trigger r1 cannot reference objects in database aux}} +do_catchsql_test 210 { + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + WITH v(m,n) AS (SELECT 5,?2) SELECT * FROM t1, v; + END; +} {1 {trigger cannot use variables}} + +finish_test diff --git a/test/without_rowid1.test b/test/without_rowid1.test index c7899cfb39..d794420ef2 100644 --- a/test/without_rowid1.test +++ b/test/without_rowid1.test @@ -238,7 +238,7 @@ do_execsql_test 5.0 { do_eqp_test 5.1 { SELECT * FROM t45 WHERE b=? AND a>? -} {/*USING INDEX i45 (b=? AND a>?)*/} +} {USING INDEX i45 (b=? AND a>?)} do_execsql_test 5.2 { SELECT * FROM t45 WHERE b='two' AND a>4 @@ -257,11 +257,11 @@ do_execsql_test 5.4 { } set queries { - 1 2 "c = 5 AND a = 1" {/*i46 (c=? AND a=?)*/} - 2 6 "c = 4 AND a < 3" {/*i46 (c=? AND a= 3" {/*i46 (c=? AND a>?)*/} - 4 1 "c = 2 AND a = 1 AND b<10" {/*i46 (c=? AND a=? AND b5" {/*i46 (c=? AND a=? AND b>?)*/} + 1 2 "c = 5 AND a = 1" {i46 (c=? AND a=?)} + 2 6 "c = 4 AND a < 3" {i46 (c=? AND a= 3" {i46 (c=? AND a>?)} + 4 1 "c = 2 AND a = 1 AND b<10" {i46 (c=? AND a=? AND b5" {i46 (c=? AND a=? AND b>?)} } foreach {tn cnt where eqp} $queries { @@ -341,6 +341,19 @@ do_execsql_test 8.1 { SELECT type, name, '|' FROM sqlite_master; } {table t1 | index t1x |} +# 2018-04-05: OSSFuzz found that the following was accessing an +# unintialized memory cell. Which was not actually causing a +# malfunction, but does cause an assert() to fail. +# +do_execsql_test 9.0 { + CREATE TABLE t2(b, c, PRIMARY KEY(b,c)) WITHOUT ROWID; + CREATE UNIQUE INDEX t2b ON t2(b); + UPDATE t2 SET b=1 WHERE b=''; +} + +do_execsql_test 10.1 { + DELETE FROM t2 WHERE b=1 +} finish_test diff --git a/test/without_rowid3.test b/test/without_rowid3.test index 387a213b99..7b4a64ed5b 100644 --- a/test/without_rowid3.test +++ b/test/without_rowid3.test @@ -949,7 +949,9 @@ ifcapable altertable { # Test the sqlite_rename_parent() function directly. # proc test_rename_parent {zCreate zOld zNew} { - db eval {SELECT sqlite_rename_parent($zCreate, $zOld, $zNew)} + db eval {SELECT sqlite_rename_table( + 'main', 'table', 't1', $zCreate, $zOld, $zNew, 0 + )} } do_test without_rowid3-14.2.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 diff --git a/test/wordcount.c b/test/wordcount.c index bc1d499f15..4a21d25ddd 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -28,6 +28,10 @@ ** (1) REPLACE INTO wordcount ** VALUES($new,ifnull((SELECT cnt FROM wordcount WHERE word=$new),0)+1); ** +** Upsert mode means: +** (1) INSERT INTO wordcount VALUES($new,1) +** ON CONFLICT(word) DO UPDATE SET cnt=cnt+1 +** ** Select mode means: ** (1) SELECT 1 FROM wordcount WHERE word=$new ** (2) INSERT INTO wordcount VALUES($new,1) -- if (1) returns nothing @@ -90,6 +94,7 @@ const char zHelp[] = " --timer Time the operation of this program\n" " --trace Enable sqlite3_trace() output.\n" " --update Use UPDATE mode\n" +" --upsert Use UPSERT mode\n" " --without-rowid Use a WITHOUT ROWID table to store the words.\n" ; @@ -208,17 +213,19 @@ static void checksumFinalize(sqlite3_context *context){ /* Define operating modes */ #define MODE_INSERT 0 #define MODE_REPLACE 1 -#define MODE_SELECT 2 -#define MODE_UPDATE 3 -#define MODE_DELETE 4 -#define MODE_QUERY 5 -#define MODE_COUNT 6 +#define MODE_UPSERT 2 +#define MODE_SELECT 3 +#define MODE_UPDATE 4 +#define MODE_DELETE 5 +#define MODE_QUERY 6 +#define MODE_COUNT 7 #define MODE_ALL (-1) /* Mode names */ static const char *azMode[] = { "--insert", "--replace", + "--upsert", "--select", "--update", "--delete", @@ -292,6 +299,8 @@ int main(int argc, char **argv){ useWithoutRowid = 1; }else if( strcmp(z,"replace")==0 ){ iMode = MODE_REPLACE; + }else if( strcmp(z,"upsert")==0 ){ + iMode = MODE_UPSERT; }else if( strcmp(z,"select")==0 ){ iMode = MODE_SELECT; }else if( strcmp(z,"insert")==0 ){ @@ -467,6 +476,14 @@ int main(int argc, char **argv){ if( rc ) fatal_error("Could not prepare the REPLACE statement: %s\n", sqlite3_errmsg(db)); } + if( iMode2==MODE_UPSERT ){ + rc = sqlite3_prepare_v2(db, + "INSERT INTO wordcount(word,cnt) VALUES(?1,1) " + "ON CONFLICT(word) DO UPDATE SET cnt=cnt+1", + -1, &pInsert, 0); + if( rc ) fatal_error("Could not prepare the UPSERT statement: %s\n", + sqlite3_errmsg(db)); + } if( iMode2==MODE_DELETE ){ rc = sqlite3_prepare_v2(db, "DELETE FROM wordcount WHERE word=?1", @@ -633,14 +650,10 @@ int main(int argc, char **argv){ printf("%s Outstanding Allocations: %d (max %d)\n",zTag,iCur,iHiwtr); sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, 0); printf("%s Pcache Overflow Bytes: %d (max %d)\n",zTag,iCur,iHiwtr); - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, 0); - printf("%s Scratch Overflow Bytes: %d (max %d)\n",zTag,iCur,iHiwtr); sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, 0); printf("%s Largest Allocation: %d bytes\n",zTag,iHiwtr); sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, 0); printf("%s Largest Pcache Allocation: %d bytes\n",zTag,iHiwtr); - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, 0); - printf("%s Largest Scratch Allocation: %d bytes\n",zTag,iHiwtr); } return 0; } diff --git a/test/zerodamage.test b/test/zerodamage.test index a87e50b7b5..83bae737df 100644 --- a/test/zerodamage.test +++ b/test/zerodamage.test @@ -74,7 +74,7 @@ do_test zerodamage-2.0 { UPDATE t1 SET y=randomblob(50) WHERE x=123; } concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] -} {0 1 2576} +} [list 0 1 [expr ([atomic_batch_write test.db]==0)*2576]] # Repeat the previous step with zero-damage turned off. This time the # maximum rollback journal size should be much larger. @@ -87,7 +87,7 @@ do_test zerodamage-2.1 { UPDATE t1 SET y=randomblob(50) WHERE x=124; } concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] -} {0 0 24704} +} [list 0 0 [expr ([atomic_batch_write test.db]==0)*24704]] if {[wal_is_capable]} { # Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the diff --git a/test/zipfile.test b/test/zipfile.test new file mode 100644 index 0000000000..ebc497786f --- /dev/null +++ b/test/zipfile.test @@ -0,0 +1,764 @@ +# 2017 December 9 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +package require Tcl 8.6 + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix zipfile + +ifcapable !vtab { + finish_test; return +} +if {[catch {load_static_extension db zipfile} error]} { + puts "Skipping zipfile tests, hit load error: $error" + finish_test; return +} +if {[catch {load_static_extension db fileio} error]} { + puts "Skipping zipfile tests, hit load error: $error" + finish_test; return +} + +proc readfile {f} { + set fd [open $f] + fconfigure $fd -translation binary -encoding binary + set data [read $fd] + close $fd + set data +} + +unset -nocomplain ::UNZIP + +if {[catch {exec unzip} msg]==0 && \ + [regexp -line {^UnZip \d+\.\d+ .*? Info-ZIP\.} $msg]} { + set ::UNZIP unzip + proc fix_stat_mode {name mode} { + if {$::tcl_platform(platform)=="windows"} { + # + # NOTE: Set or unset the write bits of the file permissions + # based on the read-only attribute because the Win32 + # version of UnZip does this. + # + set writebits 0x12; # 0o22 + set result $mode + if {[file attributes $name -readonly]} { + set result [expr {$result | $writebits}] + } else { + set result [expr {$result & ~$writebits}] + } + return $result + } else { + return $mode + } + } + proc do_unzip {file} { + forcedelete test_unzip + file mkdir test_unzip + exec $::UNZIP -d test_unzip $file + + db func modefix fix_stat_mode + + set res [db eval { + SELECT replace(name,'test_unzip/',''),modefix(name,mode),mtime,data + FROM fsdir('test_unzip') + WHERE name!='test_unzip' + ORDER BY name + }] + set res + } +} + + +# The argument is a blob (not a hex string) containing a zip archive. +# This proc removes the extended timestamp fields from the archive +# and returns the result. +# +proc remove_timestamps {blob} { + set hex [binary encode hex $blob] + set hex [string map {55540500 00000500} $hex] + binary decode hex $hex +} + + +# Argument $file is the name of a zip archive on disk. This function +# executes test cases to check that the results of each of the following +# are the same: +# +# SELECT * FROM zipfile($file) +# SELECT * FROM zipfile( readfile($file) ) +# SELECT * FROM zipfile( +# (SELECT zipfile(name,mode,mtime,data,method) FROM zipfile($file)) +# ) +# +proc do_zipfile_blob_test {tn file} { + + db func r readfile + set q1 {SELECT name,mode,mtime,method,quote(data) FROM zipfile($file)} + set q2 {SELECT name,mode,mtime,method,quote(data) FROM zipfile( r($file) )} + set q3 {SELECT name,mode,mtime,method,quote(data) FROM zipfile( + ( SELECT zipfile(name,mode,mtime,data,method) FROM zipfile($file) ) + )} + + + set r1 [db eval $q1] + set r2 [db eval $q2] + set r3 [db eval $q3] + #puts $r1 + #puts $r2 + #puts $r3 + + uplevel [list do_test $tn.1 [list set {} $r2] $r1] + uplevel [list do_test $tn.2 [list set {} $r3] $r1] +} + +# Argument $file is a zip file on disk. This command runs tests to: +# +# 1. Unpack the archive with unix command [unzip] and compare the +# results to reading the same archive using the zipfile() table +# valued function. +# +# 2. Creates a new archive with the same contents using the zipfile() +# aggregate function as follows: +# +# SELECT writefile('test_unzip.zip', +# ( SELECT zipfile(name,mode,mtime,data,method) FROM zipfile($file) ) +# ); +# +# Then tests that unpacking the new archive using [unzip] produces +# the same results as in (1). +# +proc do_unzip_test {tn file} { + db func sss strip_slash + + db eval { + SELECT writefile('test_unzip.zip', + ( SELECT zipfile(name,mode,mtime,data,method) FROM zipfile($file) ) + ); + } + + set r1 [db eval { + SELECT sss(name),mode,mtime,data FROM zipfile($file) ORDER BY name + }] + set r2 [do_unzip $file] + set r3 [do_unzip test_unzip.zip] + + uplevel [list do_test $tn.1 [list set {} $r2] $r1] + uplevel [list do_test $tn.2 [list set {} $r3] $r1] +} +proc strip_slash {in} { regsub {/$} $in {} } + +proc do_zip_tests {tn file} { + uplevel do_zipfile_blob_test $tn.1 $file + if {[info exists ::UNZIP]} { + uplevel do_unzip_test $tn.2 $file + } +} + +forcedelete test.zip +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE temp.zz USING zipfile('test.zip'); + PRAGMA table_info(zz); +} { + 0 name {} 1 {} 1 + 1 mode {} 0 {} 0 + 2 mtime {} 0 {} 0 + 3 sz {} 0 {} 0 + 4 rawdata {} 0 {} 0 + 5 data {} 0 {} 0 + 6 method {} 0 {} 0 +} + +do_catchsql_test 1.1.0.1 { + INSERT INTO zz(name, mode, mtime, sz, rawdata, method) + VALUES('f.txt', '-rw-r--r--', 1000000000, 5, 'abcde', 0); +} {1 {rawdata must be NULL}} +do_catchsql_test 1.1.0.2 { + INSERT INTO zz(name, mtime, sz, data, method) + VALUES('g.txt', 1000000002, 5, '12345', 0); +} {1 {sz must be NULL}} +do_catchsql_test 1.1.0.3 { + INSERT INTO zz(name, mtime, rawdata, method) + VALUES('g.txt', 1000000002, '12345', 0); +} {1 {rawdata must be NULL}} +do_catchsql_test 1.1.0.4 { + INSERT INTO zz(name, data, method) + VALUES('g.txt', '12345', 7); +} {1 {unknown compression method: 7}} + +do_execsql_test 1.1.1 { + INSERT INTO zz(name, mode, mtime, data, method) + VALUES('f.txt', '-rw-r--r--', 1000000000, 'abcde', 0); +} +do_execsql_test 1.1.2 { + INSERT INTO zz(name, mode, mtime, data, method) + VALUES('g.txt', NULL, 1000000002, '12345', 0); +} + +do_execsql_test 1.2 { + SELECT name, mtime, data FROM zipfile('test.zip') +} { + f.txt 1000000000 abcde + g.txt 1000000002 12345 +} +do_zip_tests 1.2a test.zip + +do_execsql_test 1.3 { + INSERT INTO zz(name, mode, mtime, data) VALUES('h.txt', + '-rw-r--r--', 1000000004, 'aaaaaaaaaabbbbbbbbbb' + ); +} +do_zip_tests 1.3a test.zip + +do_execsql_test 1.4 { + SELECT name, mtime, data, method FROM zipfile('test.zip'); +} { + f.txt 1000000000 abcde 0 + g.txt 1000000002 12345 0 + h.txt 1000000004 aaaaaaaaaabbbbbbbbbb 8 +} + +ifcapable json1 { + do_execsql_test 1.4.1 { + SELECT name, json_extract( zipfile_cds(z) , '$.crc32')!=0 + FROM zipfile('test.zip'); + } { + f.txt 1 + g.txt 1 + h.txt 1 + } +} +do_catchsql_test 1.4.2 { + SELECT zipfile_cds(mode) FROM zipfile('test.zip'); +} {0 {{} {} {}}} + +do_execsql_test 1.5.1 { + BEGIN; + INSERT INTO zz(name, mode, mtime, data, method) + VALUES('i.txt', '-rw-r--r--', 1000000006, 'zxcvb', 0); + SELECT name FROM zz; + COMMIT; +} {f.txt g.txt h.txt i.txt} +do_execsql_test 1.5.2 { + SELECT name FROM zz; +} {f.txt g.txt h.txt i.txt} +do_execsql_test 1.5.3 { + SELECT data FROM zz WHERE name='i.txt'; +} {zxcvb} + +do_execsql_test 1.6.0 { + DELETE FROM zz WHERE name='g.txt'; + SELECT name FROM zz; +} {f.txt h.txt i.txt} + +do_execsql_test 1.6.1 { + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + f.txt 33188 1000000000 abcde 0 + h.txt 33188 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 1000000006 zxcvb 0 +} +do_zip_tests 1.6.1a test.zip + +do_execsql_test 1.6.2 { + UPDATE zz SET mtime=4 WHERE name='i.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + f.txt 33188 1000000000 abcde 0 + h.txt 33188 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +} + +if {$::tcl_platform(platform)=="unix"} { + set modes -rw-r--r-x + set perms 33189 +} else { + set modes -rw-r--r--; # no execute bits on Win32 + set perms 33188 +} + +do_execsql_test 1.6.3 { + UPDATE zz SET mode=$modes WHERE name='h.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} [string map [list %perms% $perms] { + f.txt 33188 1000000000 abcde 0 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +}] +do_zip_tests 1.6.3a test.zip + +do_execsql_test 1.6.4 { + UPDATE zz SET name = 'blue.txt' WHERE name='f.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} [string map [list %perms% $perms] { + blue.txt 33188 1000000000 abcde 0 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +}] +do_zip_tests 1.6.4a test.zip + +do_execsql_test 1.6.5 { + UPDATE zz SET data = 'edcba' WHERE name='blue.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} [string map [list %perms% $perms] { + blue.txt 33188 1000000000 edcba 0 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +}] + +do_execsql_test 1.6.6 { + UPDATE zz SET mode=NULL, data = NULL WHERE name='blue.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} [string map [list %perms% $perms] { + blue.txt/ 16877 1000000000 {} 0 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +}] + +do_catchsql_test 1.6.7 { + UPDATE zz SET data=NULL WHERE name='i.txt' +} {1 {zipfile: mode does not match data}} +do_execsql_test 1.6.8 { + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} [string map [list %perms% $perms] { + blue.txt/ 16877 1000000000 {} 0 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +}] + +do_execsql_test 1.6.9 { + UPDATE zz SET data = '' WHERE name='i.txt'; + SELECT name,mode,mtime,data,method from zipfile('test.zip'); +} [string map [list %perms% $perms] { + blue.txt/ 16877 1000000000 {} 0 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 {} 0 +}] + +do_execsql_test 1.6.10 { + SELECT a.name, a.data + FROM zz AS a, zz AS b + WHERE a.name=+b.name AND +a.mode=b.mode +} { + blue.txt/ {} + h.txt aaaaaaaaaabbbbbbbbbb + i.txt {} +} + +do_execsql_test 1.6.11 { + SELECT name, data FROM zz WHERE name LIKE '%txt' +} { + h.txt aaaaaaaaaabbbbbbbbbb + i.txt {} +} + +do_execsql_test 1.7 { + DELETE FROM zz; + SELECT * FROM zz; +} {} + +#------------------------------------------------------------------------- +db close +forcedelete test.zip +reset_db +load_static_extension db fileio +load_static_extension db zipfile +do_execsql_test 2.1 { + CREATE VIRTUAL TABLE zzz USING zipfile('test.zip'); + INSERT INTO zzz(name, mode) VALUES('dirname', 'drwxr-xr-x'); + SELECT name, mode, data FROM zzz; +} {dirname/ 16877 {}} +do_execsql_test 2.2 { + INSERT INTO zzz(name, data) VALUES('dirname2', NULL); + INSERT INTO zzz(name, data) VALUES('dirname2/file1.txt', 'abcdefghijklmnop'); + SELECT name, mode, data FROM zzz; +} { + dirname/ 16877 {} + dirname2/ 16877 {} + dirname2/file1.txt 33188 abcdefghijklmnop +} + +do_catchsql_test 2.3 { + UPDATE zzz SET name = 'dirname3' WHERE name = 'dirname/'; +} {0 {}} +do_execsql_test 2.4 { + SELECT name, mode, data FROM zzz; +} { + dirname3/ 16877 {} + dirname2/ 16877 {} + dirname2/file1.txt 33188 abcdefghijklmnop +} +do_zip_tests 2.4a test.zip + +# Check that the [unzip] utility can unpack our archive. +# +if {[info exists ::UNZIP]} { + do_test 2.5.1 { + forcedelete dirname + forcedelete dirname2 + if {$::tcl_platform(platform)=="unix"} { + set null /dev/null + } else { + set null NUL + } + set rc [catch { exec $::UNZIP test.zip > $null } msg] + list $rc $msg + } {0 {}} + do_test 2.5.2 { file isdir dirname3 } 1 + do_test 2.5.3 { file isdir dirname2 } 1 + do_test 2.5.4 { file isdir dirname2/file1.txt } 0 + do_test 2.5.5 { + set fd [open dirname2/file1.txt] + set data [read $fd] + close $fd + set data + } {abcdefghijklmnop} +} + +#------------------------------------------------------------------------- +reset_db +forcedelete test.zip +load_static_extension db zipfile +load_static_extension db fileio + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE temp.x1 USING zipfile('test.zip'); + INSERT INTO x1(name, data) VALUES('dir1/', NULL); + INSERT INTO x1(name, data) VALUES('file1', '1234'); + INSERT INTO x1(name, data) VALUES('dir1/file2', '5678'); +} +foreach {tn fname} { + 1 dir1 + 2 file1 + 3 dir1/file2 +} { + do_catchsql_test 3.1.$tn.0 { + INSERT INTO x1(name, data) VALUES($fname, NULL); + } [list 1 "duplicate name: \"$fname/\""] + do_catchsql_test 3.1.$tn.1 { + INSERT INTO x1(name, data) VALUES($fname || '/', NULL); + } [list 1 "duplicate name: \"$fname/\""] + do_catchsql_test 3.1.$tn.2 { + INSERT INTO x1(name, data) VALUES($fname, 'abcd'); + } [list 1 "duplicate name: \"$fname\""] +} + +do_catchsql_test 3.2 { + SELECT rowid FROM x1 +} {1 {no such column: rowid}} + +#------------------------------------------------------------------------- +# Test some error conditions. +# +do_catchsql_test 4.1 { + CREATE VIRTUAL TABLE yyy USING zipfile(); +} {1 {zipfile constructor requires one argument}} +do_catchsql_test 4.2 { + CREATE VIRTUAL TABLE yyy USING zipfile('test.zip', 'test.zip'); +} {1 {zipfile constructor requires one argument}} + +do_catchsql_test 4.3 { + SELECT * FROM zipfile() +} {1 {zipfile() function requires an argument}} + +do_catchsql_test 4.4 { + SELECT * FROM zipfile('/path/that/does/not/exist') +} {1 {cannot open file: /path/that/does/not/exist}} + +foreach {tn mode} { + 1 abcd + 2 brwxrwxrwx + 3 lrwxrrxrwx +} { + do_catchsql_test 4.5.$tn { + WITH m(m) AS ( SELECT $mode) + SELECT zipfile('a.txt', m, 1000, 'xyz') FROM m + } [list 1 "zipfile: parse error in mode: $mode"] +} + +do_catchsql_test 4.6 { + WITH c(name,data) AS ( SELECT 'a.txt', 'abc') + SELECT zipfile(name) FROM c +} {1 {wrong number of arguments to function zipfile()}} + +do_catchsql_test 4.7 { + WITH c(name,data) AS ( + SELECT 'a.txt', 'abc' UNION ALL + SELECT NULL, 'def' + ) + SELECT zipfile(name,data) FROM c +} {1 {first argument to zipfile() must be non-NULL}} + +do_catchsql_test 4.8 { + WITH c(name,data,method) AS ( + SELECT 'a.txt', 'abc', 0 + UNION SELECT 'b.txt', 'def', 8 + UNION SELECT 'c.txt', 'ghi', 16 + ) + SELECT zipfile(name,NULL,NULL,data,method) FROM c +} {1 {illegal method value: 16}} + +do_catchsql_test 4.9 { + WITH c(name,data) AS ( + SELECT 'a.txt', 'abc' + UNION SELECT 'b.txt', 'def' + UNION SELECT 'c.txt/', 'ghi' + ) + SELECT zipfile(name,NULL,NULL,data) FROM c +} {1 {non-directory name must not end with /}} + +#-------------------------------------------------------------------------- + +db func rt remove_timestamps +do_execsql_test 5.0 { + WITH c(name,mtime,data) AS ( + SELECT 'a.txt', 946684800, 'abc' + ) + SELECT name,mtime,data FROM zipfile( + ( SELECT rt( zipfile(name,NULL,mtime,data,NULL) ) FROM c ) + ) +} { + a.txt 946684800 abc +} + +if {[info exists ::UNZIP]} { +ifcapable datetime { + forcedelete test1.zip test2.zip + do_test 6.0 { + execsql { + WITH c(name,mtime,data) AS ( + SELECT 'a.txt', 946684800, 'abc' UNION ALL + SELECT 'b.txt', 1000000000, 'abc' UNION ALL + SELECT 'c.txt', 1111111000, 'abc' + ) + SELECT writefile('test1.zip', rt( zipfile(name, NULL, mtime, data) ) ), + writefile('test2.zip', ( zipfile(name, NULL, mtime, data) ) ) + FROM c; + } + forcedelete test_unzip + file mkdir test_unzip + exec $::UNZIP -d test_unzip test1.zip + + db eval { + SELECT name, strftime('%s', mtime, 'unixepoch', 'localtime') + FROM fsdir('test_unzip') WHERE name!='test_unzip' + ORDER BY name + } + } [list {*}{ + test_unzip/a.txt 946684800 + test_unzip/b.txt 1000000000 + test_unzip/c.txt 1111111000 + }] + + # fsdir() issue reported on the mailing list on 2018-03-14 by Jack Thaw. + do_test 6.0b { + db eval { + SELECT sum(name LIKE '%/a.txt') + FROM (VALUES(1),(2),(3)) CROSS JOIN fsdir('test_unzip') + } + } {3} + + do_execsql_test 6.1 { + SELECT name, mtime, data FROM zipfile('test1.zip') + } { + a.txt 946684800 abc + b.txt 1000000000 abc + c.txt 1111111000 abc + } + + do_test 6.2 { + forcedelete test_unzip + file mkdir test_unzip + exec $::UNZIP -d test_unzip test2.zip + + db eval { + SELECT name, mtime + FROM fsdir('test_unzip') WHERE name!='test_unzip' + ORDER BY name + } + } [list {*}{ + test_unzip/a.txt 946684800 + test_unzip/b.txt 1000000000 + test_unzip/c.txt 1111111000 + }] + + do_execsql_test 6.3 { + SELECT name, mtime, sz, rawdata, data FROM zipfile('test2.zip') + } { + a.txt 946684800 3 abc abc + b.txt 1000000000 3 abc abc + c.txt 1111111000 3 abc abc + } +} +} + +#------------------------------------------------------------------------- +# Force an IO error by truncating the zip archive to zero bytes in size +# while it is being read. +forcedelete test.zip +do_test 7.0 { + execsql { + WITH c(name,data) AS ( + SELECT '1', randomblob(1000000) UNION ALL + SELECT '2', randomblob(1000000) UNION ALL + SELECT '3', randomblob(1000000) + ) + SELECT writefile('test.zip', zipfile(name, data) ) FROM c; + } + + list [catch { + db eval { SELECT name, data FROM zipfile('test.zip') } { + if {$name==2} { close [open test.zip w+] } + } + } msg] $msg +} {1 {error in fread()}} + +forcedelete test.zip +do_execsql_test 8.0.1 { + CREATE VIRTUAL TABLE zz USING zipfile('test.zip'); + BEGIN; + INSERT INTO zz(name, data) VALUES('a.txt', '1'); + INSERT INTO zz(name, data) VALUES('b.txt', '2'); + INSERT INTO zz(name, data) VALUES('c.txt', '1'); + INSERT INTO zz(name, data) VALUES('d.txt', '2'); + SELECT name, data FROM zz; +} { + a.txt 1 b.txt 2 c.txt 1 d.txt 2 +} +do_test 8.0.2 { + db eval { SELECT name, data FROM zz } { + if { $data=="2" } { db eval { DELETE FROM zz WHERE name=$name } } + } + execsql { SELECT name, data FROM zz } +} {a.txt 1 c.txt 1} +do_test 8.0.3 { + db eval { SELECT name, data FROM zz } { + db eval { DELETE FROM zz WHERE name=$name } + } + execsql { SELECT name, data FROM zz } +} {} +execsql COMMIT + +catch { forcedelete test_unzip } +catch { file mkdir test_unzip } +do_execsql_test 8.1.1 { + CREATE VIRTUAL TABLE nogood USING zipfile('test_unzip'); +} +do_catchsql_test 8.1.2 { + INSERT INTO nogood(name, data) VALUES('abc', 'def'); +} {1 {zipfile: failed to open file test_unzip for writing}} + +do_execsql_test 8.2.1 { + DROP TABLE nogood; + BEGIN; + CREATE VIRTUAL TABLE nogood USING zipfile('test_unzip'); +} +do_catchsql_test 8.2.2 { + INSERT INTO nogood(name, data) VALUES('abc', 'def'); +} {1 {zipfile: failed to open file test_unzip for writing}} +do_execsql_test 8.2.3 { + COMMIT; +} + +forcedelete test.zip +do_execsql_test 8.3.1 { + BEGIN; + CREATE VIRTUAL TABLE ok USING zipfile('test.zip'); + INSERT INTO ok(name, data) VALUES ('sqlite3', 'elf'); + COMMIT; +} + +#------------------------------------------------------------------------- +# Test that the zipfile aggregate correctly adds and removes "/" from +# the ends of directory file names. +do_execsql_test 9.0 { + WITH src(nm) AS ( + VALUES('dir1') UNION ALL + VALUES('dir2/') UNION ALL + VALUES('dir3//') UNION ALL + VALUES('dir4///') UNION ALL + VALUES('/') + ) + SELECT name FROM zipfile((SELECT zipfile(nm, NULL) FROM src)) +} {dir1/ dir2/ dir3/ dir4/ /} + +#------------------------------------------------------------------------- +# INSERT OR REPLACE and INSERT OR IGNORE +# +catch {db close} +forcedelete test.zip test.db +sqlite3 db :memory: +load_static_extension db zipfile +load_static_extension db fileio + +do_execsql_test 10.0 { + CREATE VIRTUAL TABLE z USING zipfile('test.zip'); +} {} +do_catchsql_test 10.1 { + INSERT INTO z(name,data) VALUES('a0','one'),('a0','two'); +} {1 {duplicate name: "a0"}} +do_execsql_test 10.2 { + SELECT name, data FROM z; +} {a0 one} +do_execsql_test 10.3 { + REPLACE INTO z(name,data) VALUES('a0','three'),('a0','four'); +} {} +do_execsql_test 10.4 { + SELECT name, data FROM z; +} {a0 four} +do_execsql_test 10.5 { + INSERT OR IGNORE INTO z(name,data) VALUES('a0','five'),('a0','six'); +} {} +do_execsql_test 10.6 { + SELECT name, data FROM z; +} {a0 four} + +do_execsql_test 11.1 { + DELETE FROM z; +} {} +do_execsql_test 11.2 { + SELECT name, data FROM z; +} {} +do_execsql_test 11.3 { + INSERT INTO z (name,data) VALUES ('b0','one'); + SELECT name, data FROM z; +} {b0 one} +do_execsql_test 11.4 { + UPDATE z SET name = 'b1' WHERE name = 'b0'; + SELECT name, data FROM z; +} {b1 one} +do_execsql_test 11.5 { + INSERT INTO z (name,data) VALUES ('b0','one'); + SELECT name, data FROM z ORDER BY name; +} {b0 one b1 one} +do_catchsql_test 11.6 { + UPDATE z SET name = 'b1' WHERE name = 'b0'; +} {1 {duplicate name: "b1"}} +do_execsql_test 11.7 { + UPDATE z SET data = 'two' WHERE name = 'b0'; + SELECT name, data FROM z ORDER BY name; +} {b0 two b1 one} +do_catchsql_test 11.8 { + UPDATE z SET name = 'b1'; +} {1 {duplicate name: "b1"}} +do_catchsql_test 11.9 { + UPDATE z SET name = 'b2'; +} {1 {duplicate name: "b2"}} +do_execsql_test 11.10 { + UPDATE z SET name = name; + SELECT name, data FROM z ORDER BY name; +} {b0 two b2 one} +do_execsql_test 11.11 { + UPDATE z SET name = name || 'suffix'; + SELECT name, data FROM z ORDER BY name; +} {b0suffix two b2suffix one} + +finish_test diff --git a/test/zipfile2.test b/test/zipfile2.test new file mode 100644 index 0000000000..e9b93cab12 --- /dev/null +++ b/test/zipfile2.test @@ -0,0 +1,244 @@ +# 2018 January 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +package require Tcl 8.6 + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix zipfile2 + +ifcapable !vtab { + finish_test; return +} +if {[catch {load_static_extension db zipfile} error]} { + puts "Skipping zipfile2 tests, hit load error: $error" + finish_test; return +} + +proc blobliteral {str} { + set concat [string map {" " "" "\n" ""} $str] + return "X'$concat'" +} + +proc blob {str} { + binary decode hex $str +} + +proc findall {needle haystack} { + set L [list] + set start 0 + while { [set idx [string first $needle $haystack $start]]>=0 } { + lappend L $idx + set start [expr $idx+1] + } + set L +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE aaa USING zipfile('testzip'); + CREATE VIRTUAL TABLE bbb USING zipfile("testzip"); + CREATE VIRTUAL TABLE ccc USING zipfile(`testzip`); + CREATE VIRTUAL TABLE ddd USING zipfile([testzip]); + CREATE VIRTUAL TABLE eee USING zipfile(testzip); + CREATE VIRTUAL TABLE fff USING zipfile('test''zip'); +} + +do_test 2.0 { + forcedelete testdir + file mkdir testdir + execsql { CREATE VIRTUAL TABLE hhh USING zipfile('testdir') } + lindex [catchsql { + SELECT * FROM hhh; + INSERT INTO hhh(name, data) VALUES('1.txt', 'file data'); + }] 0 +} 1 + + +set archive { + 504B0304140000080000D4A52BEC09F3B6E0110000001100000005000900612E + 747874555405000140420F00636F6E74656E7473206F6620612E747874504B03 + 04140000080000D4A52BECD98916A7110000001100000005000900622E747874 + 555405000140420F00636F6E74656E7473206F6620622E747874504B01021E03 + 140000080000D4A52BEC09F3B6E0110000001100000005000900000000000000 + 0000A48100000000612E747874555405000140420F00504B01021E0314000008 + 0000D4A52BECD98916A71100000011000000050009000000000000000000A481 + 3D000000622E747874555405000140420F00504B050600000000020002007800 + 00007A0000000000 +} + +if 0 { + # This test is broken - the archive generated is slightly different + # depending on the zlib version used. + do_execsql_test 3.1 { + WITH contents(name,mtime,data) AS ( + VALUES('a.txt', 1000000, 'contents of a.txt') UNION ALL + VALUES('b.txt', 1000000, 'contents of b.txt') + ) SELECT quote( zipfile(name,NULL,mtime,data) ) FROM contents; + } [blobliteral $archive] +} + + +set blob [blob $archive] +do_execsql_test 3.2 { + SELECT name,mtime,data FROM zipfile($blob) +} { + a.txt 1000000 {contents of a.txt} + b.txt 1000000 {contents of b.txt} +} + +# Corrupt each of the 0x50 0x4B (ascii "PK") headers in the file +# Test that in each case this causes an error. +# +set L [findall 504B $archive] +for {set i 0} {$i < [llength $L]} {incr i} { + set idx [lindex $L $i] + set a [string replace $archive $idx [expr $idx+3] 0000] + set blob [blob $a] + do_catchsql_test 3.3.$i { + SELECT name,mtime,data FROM zipfile($blob) + } {/1 .*/} +} + +# Change the "extra info id" for all extended-timestamp fields. +set L [findall 5554 $archive] +for {set i 0} {$i < [llength $L]} {incr i} { + set idx [lindex $L $i] + set a [string replace $archive $idx [expr $idx+3] 1234] + set blob [blob $a] + do_execsql_test 3.4.$i { + SELECT name,data FROM zipfile($blob) + } { + a.txt {contents of a.txt} + b.txt {contents of b.txt} + } +} + +for {set i 0} {$i < [llength $L]} {incr i} { + set idx [lindex $L $i] + set a [string replace $archive [expr $idx+8] [expr $idx+9] 00] + set blob [blob $a] + do_execsql_test 3.5.$i { + SELECT name,data FROM zipfile($blob) + } { + a.txt {contents of a.txt} + b.txt {contents of b.txt} + } +} + +# set blob [db one { +# WITH contents(name,mtime,data) AS ( +# VALUES('a.txt', 1000000, 'aaaaaaaaaaaaaaaaaaaaaaa') +# ) SELECT quote( zipfile(name,NULL,mtime,data) ) FROM contents; +# }] +# set blob [string range $blob 2 end] +# set blob [string range $blob 0 end-1] +# while {[string length $blob]>0} { +# puts [string range $blob 0 63] +# set blob [string range $blob 64 end] +# } +# exit + +set archive2 { + 504B0304140000080800D4A52BEC08F54C6E050000001700000005000900612E + 747874555405000140420F004B4CC40A00504B01021E03140000080800D4A52B + EC08F54C6E0500000017000000050009000000000000000000A4810000000061 + 2E747874555405000140420F00504B050600000000010001003C000000310000 + 000000 +} +set blob [blob $archive2] +do_execsql_test 4.0 { + SELECT name,mtime,data,method FROM zipfile($blob) +} { + a.txt 1000000 aaaaaaaaaaaaaaaaaaaaaaa 8 +} + +set L [findall 17000000 $archive2] +set a $archive2 +foreach i $L { set a [string replace $a $i [expr $i+7] 16000000] } +set blob [blob $a] +do_catchsql_test 4.1 { + SELECT name,mtime,data,method FROM zipfile($blob) +} {1 {inflate() failed (0)}} + +# Check the response to an unknown compression method (set data to NULL). +set blob [blob [string map {0800 0900} $archive2]] +do_execsql_test 4.2 { + SELECT name,mtime,data IS NULL,method FROM zipfile($blob) +} {a.txt 1000000 1 9} + +# Corrupt the EOCDS signature bytes in various ways. +foreach {tn sub} { + 1 {504B0500} + 2 {504B0006} + 3 {50000506} + 4 {004B0506} +} { + set blob [blob [string map [list 504B0506 $sub] $archive2]] + do_catchsql_test 4.3.$tn { + SELECT * FROM zipfile($blob) + } {1 {cannot find end of central directory record}} +} + +#------------------------------------------------------------------------- +# Test that a zero-length file with a '/' at the end is treated as +# a directory (data IS NULL). Even if the mode doesn't indicate +# that it is a directory. + +do_test 5.0 { + set blob [db one { + WITH c(n, d) AS ( + SELECT 'notadir', '' + ) + SELECT zipfile(n, d) FROM c + }] + + set hex [binary encode hex $blob] + set hex [string map {6e6f7461646972 6e6f746164692f} $hex] + set blob2 [binary decode hex $hex] + + execsql { SELECT name, data IS NULL FROM zipfile($blob2) } +} {notadi/ 1} + +#------------------------------------------------------------------------- +# Test that duplicate entries may not be created using UPDATE +# statements. +# +forcedelete test.zip +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); + INSERT INTO temp.zip (name,data) VALUES ('test1','test'); + INSERT INTO temp.zip (name,data) VALUES ('test2','test'); +} +do_catchsql_test 6.1 { + UPDATE temp.zip SET name='test1' WHERE name='test2' +} {1 {duplicate name: "test1"}} + +forcedelete test.zip +do_catchsql_test 6.2 { + DROP TABLE zip; + CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); + INSERT INTO temp.zip (name,data) VALUES ('test','test'); + UPDATE temp.zip set name=name||'new' where name='test'; + INSERT INTO temp.zip (name,data) VALUES ('test','test'); + UPDATE temp.zip set name=name||'new' where name='test'; +} {1 {duplicate name: "testnew"}} + +forcedelete test.zip +do_execsql_test 6.3 { + INSERT INTO temp.zip (name,data) VALUES ('test1','test'); + INSERT INTO temp.zip (name,data) VALUES ('test2','test'); + UPDATE OR REPLACE zip SET name='test2' WHERE name='test1'; + SELECT name FROM zip; +} {test2} + +finish_test + diff --git a/test/zipfilefault.test b/test/zipfilefault.test new file mode 100644 index 0000000000..f5e2cd5cb6 --- /dev/null +++ b/test/zipfilefault.test @@ -0,0 +1,166 @@ +# 2018 January 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set testprefix zipfilefault + +ifcapable !vtab { + finish_test; return +} +if {[catch {load_static_extension db zipfile} error]} { + puts "Skipping zipfile2 tests, hit load error: $error" + finish_test; return +} + +faultsim_save_and_close +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen + load_static_extension db zipfile + execsql { DROP TABLE IF EXISTS aaa } +} -body { + execsql { CREATE VIRTUAL TABLE aaa USING zipfile('test.zip') } +} -test { + faultsim_test_result {0 {}} +} + +forcedelete test.zip +sqlite3 db test.db +load_static_extension db zipfile +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE setup USING zipfile('test.zip'); + INSERT INTO setup(name, data) VALUES('a.txt', '1234567890'); +} + +do_faultsim_test 2.1 -faults oom* -body { + execsql { SELECT name,data FROM zipfile('test.zip') } +} -test { + faultsim_test_result {0 {a.txt 1234567890}} +} +ifcapable json1 { + do_faultsim_test 2.2 -faults oom* -body { + execsql { + SELECT json_extract( zipfile_cds(z), '$.version-made-by' ) + FROM zipfile('test.zip') + } + } -test { + faultsim_test_result {0 798} + } +} + +forcedelete test.zip +reset_db +load_static_extension db zipfile +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE setup USING zipfile('test.zip'); + INSERT INTO setup(name, data) VALUES('a.txt', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa'); +} + +do_faultsim_test 3 -faults oom* -body { + execsql { SELECT name,data FROM zipfile('test.zip') } +} -test { + faultsim_test_result {0 {a.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaa}} +} + +do_faultsim_test 4 -faults oom* -body { + execsql { + WITH c(n, d) AS ( + SELECT 1, 'aaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb' + ) + SELECT name, data FROM zipfile( + (SELECT zipfile(n, d) FROM c) + ); + } +} -test { + faultsim_test_result {0 {1 aaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb}} +} + +reset_db +sqlite3_db_config_lookaside db 0 0 0 +load_static_extension db zipfile + +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE setup USING zipfile('test.zip') +} + +do_faultsim_test 5.1 -faults oom* -prep { + forcedelete test.zip +} -body { + execsql { + INSERT INTO setup(name, data) + VALUES('a.txt', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa'); + } +} -test { + faultsim_test_result {0 {}} +} + +do_faultsim_test 5.2 -faults oom* -prep { + forcedelete test.zip +} -body { + execsql { + INSERT INTO setup(name, data) VALUES('dir', NULL) + } +} -test { + faultsim_test_result {0 {}} +} + +do_faultsim_test 5.3 -faults oom* -prep { + forcedelete test.zip + execsql { + DROP TABLE IF EXISTS setup; + BEGIN; + CREATE VIRTUAL TABLE setup USING zipfile('test.zip') + } +} -body { + execsql { + INSERT INTO setup(name, data) VALUES('dir', NULL) + } +} -test { + catchsql { COMMIT } + faultsim_test_result {0 {}} +} + +do_faultsim_test 6.1 -faults oom* -body { + execsql { + WITH c(n, d) AS ( + VALUES('a.txt', '1234567890') UNION ALL + VALUES('dir', NULL) + ) + SELECT zipfile(n, d) IS NULL FROM c; + } +} -test { + faultsim_test_result {0 0} +} + +set big [string repeat 0123456789 1000] +do_faultsim_test 6.2 -faults oom* -body { + execsql { + WITH c(n, d) AS ( + VALUES('a.txt', $big) + ) + SELECT zipfile(n, NULL, NULL, d, 0) IS NULL FROM c; + } +} -test { + faultsim_test_result {0 0} +} + +do_faultsim_test 7.0 -faults oom* -prep { + catch { db close } + sqlite3 db "" +} -body { + load_static_extension db zipfile +} -test { +} + + +finish_test diff --git a/tool/addopcodes.tcl b/tool/addopcodes.tcl index dfd7fac88c..070779029b 100644 --- a/tool/addopcodes.tcl +++ b/tool/addopcodes.tcl @@ -22,6 +22,7 @@ close $in # ILLEGAL *must* be the last two token codes and they must be in that order. # set extras { + TRUEFALSE ISNOT FUNCTION COLUMN @@ -29,6 +30,7 @@ set extras { AGG_COLUMN UMINUS UPLUS + TRUTH REGISTER VECTOR SELECT_COLUMN diff --git a/tool/lemon.c b/tool/lemon.c index acc5450c99..1fca8b9755 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -270,6 +270,8 @@ struct symbol { int dtnum; /* The data type number. In the parser, the value ** stack is a union. The .yy%d element of this ** union is the correct data type for this object */ + int bContent; /* True if this symbol ever carries content - if + ** it is ever more than just syntax */ /* The following fields are used by MULTITERMINALs only */ int nsubsym; /* Number of constituent symbols in the MULTI */ struct symbol **subsym; /* Array of constituent symbols */ @@ -384,12 +386,19 @@ struct lemon { int nrule; /* Number of rules */ int nsymbol; /* Number of terminal and nonterminal symbols */ int nterminal; /* Number of terminal symbols */ + int minShiftReduce; /* Minimum shift-reduce action value */ + int errAction; /* Error action value */ + int accAction; /* Accept action value */ + int noAction; /* No-op action value */ + int minReduce; /* Minimum reduce action */ + int maxAction; /* Maximum action value of any kind */ struct symbol **symbols; /* Sorted array of pointers to symbols */ int errorcnt; /* Number of errors */ struct symbol *errsym; /* The error symbol */ struct symbol *wildcard; /* Token that matches anything */ char *name; /* Name of the generated parser */ char *arg; /* Declaration of the 3th argument to parser */ + char *ctx; /* Declaration of 2nd argument to constructor */ char *tokentype; /* Type of terminal symbols in the parser stack */ char *vartype; /* The default type of non-terminal symbols */ char *start; /* Name of the start symbol for the grammar */ @@ -407,6 +416,7 @@ struct lemon { char *tokenprefix; /* A prefix added to token names in the .h file */ int nconflict; /* Number of parsing conflicts */ int nactiontab; /* Number of entries in the yy_action[] table */ + int nlookaheadtab; /* Number of entries in yy_lookahead[] */ int tablesize; /* Total table size of all tables in bytes */ int basisflag; /* Print only basis configurations */ int has_fallback; /* True if any %fallback is seen in the grammar */ @@ -583,10 +593,12 @@ struct acttab { int mxLookahead; /* Maximum aLookahead[].lookahead */ int nLookahead; /* Used slots in aLookahead[] */ int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ + int nterminal; /* Number of terminal symbols */ + int nsymbol; /* total number of symbols */ }; /* Return the number of entries in the yy_action table */ -#define acttab_size(X) ((X)->nAction) +#define acttab_lookahead_size(X) ((X)->nAction) /* The value for the N-th entry in yy_action */ #define acttab_yyaction(X,N) ((X)->aAction[N].action) @@ -602,13 +614,15 @@ void acttab_free(acttab *p){ } /* Allocate a new acttab structure */ -acttab *acttab_alloc(void){ +acttab *acttab_alloc(int nsymbol, int nterminal){ acttab *p = (acttab *) calloc( 1, sizeof(*p) ); if( p==0 ){ fprintf(stderr,"Unable to allocate memory for a new acttab."); exit(1); } memset(p, 0, sizeof(*p)); + p->nsymbol = nsymbol; + p->nterminal = nterminal; return p; } @@ -649,16 +663,24 @@ void acttab_action(acttab *p, int lookahead, int action){ ** to an empty set in preparation for a new round of acttab_action() calls. ** ** Return the offset into the action table of the new transaction. +** +** If the makeItSafe parameter is true, then the offset is chosen so that +** it is impossible to overread the yy_lookaside[] table regardless of +** the lookaside token. This is done for the terminal symbols, as they +** come from external inputs and can contain syntax errors. When makeItSafe +** is false, there is more flexibility in selecting offsets, resulting in +** a smaller table. For non-terminal symbols, which are never syntax errors, +** makeItSafe can be false. */ -int acttab_insert(acttab *p){ - int i, j, k, n; +int acttab_insert(acttab *p, int makeItSafe){ + int i, j, k, n, end; assert( p->nLookahead>0 ); /* Make sure we have enough space to hold the expanded action table ** in the worst case. The worst case occurs if the transaction set ** must be appended to the current action table */ - n = p->mxLookahead + 1; + n = p->nsymbol + 1; if( p->nAction + n >= p->nActionAlloc ){ int oldAlloc = p->nActionAlloc; p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; @@ -680,7 +702,8 @@ int acttab_insert(acttab *p){ ** ** i is the index in p->aAction[] where p->mnLookahead is inserted. */ - for(i=p->nAction-1; i>=0; i--){ + end = makeItSafe ? p->mnLookahead : 0; + for(i=p->nAction-1; i>=end; i--){ if( p->aAction[i].lookahead==p->mnLookahead ){ /* All lookaheads and actions in the aLookahead[] transaction ** must match against the candidate aAction[i] entry. */ @@ -710,12 +733,13 @@ int acttab_insert(acttab *p){ ** an empty offset in the aAction[] table in which we can add the ** aLookahead[] transaction. */ - if( i<0 ){ + if( inAction, which means the ** transaction will be appended. */ - for(i=0; inActionAlloc - p->mxLookahead; i++){ + i = makeItSafe ? p->mnLookahead : 0; + for(; inActionAlloc - p->mxLookahead; i++){ if( p->aAction[i].lookahead<0 ){ for(j=0; jnLookahead; j++){ k = p->aLookahead[j].lookahead - p->mnLookahead + i; @@ -733,11 +757,19 @@ int acttab_insert(acttab *p){ } } /* Insert transaction set at index i. */ +#if 0 + printf("Acttab:"); + for(j=0; jnLookahead; j++){ + printf(" %d", p->aLookahead[j].lookahead); + } + printf(" inserted at %d\n", i); +#endif for(j=0; jnLookahead; j++){ k = p->aLookahead[j].lookahead - p->mnLookahead + i; p->aAction[k] = p->aLookahead[j]; if( k>=p->nAction ) p->nAction = k+1; } + if( makeItSafe && i+p->nterminal>=p->nAction ) p->nAction = i+p->nterminal+1; p->nLookahead = 0; /* Return the offset that is added to the lookahead in order to get the @@ -745,6 +777,16 @@ int acttab_insert(acttab *p){ return i - p->mnLookahead; } +/* +** Return the size of the action table without the trailing syntax error +** entries. +*/ +int acttab_action_size(acttab *p){ + int n = p->nAction; + while( n>0 && p->aAction[n-1].lookahead<0 ){ n--; } + return n; +} + /********************** From the file "build.c" *****************************/ /* ** Routines to construction the finite state machine for the LEMON @@ -1496,6 +1538,18 @@ static void handle_D_option(char *z){ *z = 0; } +/* Rember the name of the output directory +*/ +static char *outputDir = NULL; +static void handle_d_option(char *z){ + outputDir = (char *) malloc( lemonStrlen(z)+1 ); + if( outputDir==0 ){ + fprintf(stderr,"out of memory\n"); + exit(1); + } + lemon_strcpy(outputDir, z); +} + static char *user_templatename = NULL; static void handle_T_option(char *z){ user_templatename = (char *) malloc( lemonStrlen(z)+1 ); @@ -1577,9 +1631,11 @@ int main(int argc, char **argv) static int mhflag = 0; static int nolinenosflag = 0; static int noResort = 0; + static struct s_options options[] = { {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, + {OPT_FSTR, "d", (char*)&handle_d_option, "Output directory. Default '.'"}, {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, {OPT_FSTR, "f", 0, "Ignored. (Placeholder for -f compiler options.)"}, {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, @@ -1624,8 +1680,6 @@ int main(int argc, char **argv) lem.basisflag = basisflag; lem.nolinenosflag = nolinenosflag; Symbol_new("$"); - lem.errsym = Symbol_new("error"); - lem.errsym->useCnt = 0; /* Parse the input file */ Parse(&lem); @@ -1634,6 +1688,7 @@ int main(int argc, char **argv) fprintf(stderr,"Empty grammar.\n"); exit(1); } + lem.errsym = Symbol_find("error"); /* Count and index the symbols of the grammar */ Symbol_new("{default}"); @@ -1718,6 +1773,7 @@ int main(int argc, char **argv) stats_line("states", lem.nxstate); stats_line("conflicts", lem.nconflict); stats_line("action table entries", lem.nactiontab); + stats_line("lookahead table entries", lem.nlookaheadtab); stats_line("total table size (bytes)", lem.tablesize); } if( lem.nconflict > 0 ){ @@ -2323,6 +2379,7 @@ to follow the previous rule."); for(i=0; inrhs; i++){ rp->rhs[i] = psp->rhs[i]; rp->rhsalias[i] = psp->alias[i]; + if( rp->rhsalias[i]!=0 ){ rp->rhs[i]->bContent = 1; } } rp->lhs = psp->lhs; rp->lhsalias = psp->lhsalias; @@ -2440,6 +2497,9 @@ to follow the previous rule."); }else if( strcmp(x,"extra_argument")==0 ){ psp->declargslot = &(psp->gp->arg); psp->insertLineMacro = 0; + }else if( strcmp(x,"extra_context")==0 ){ + psp->declargslot = &(psp->gp->ctx); + psp->insertLineMacro = 0; }else if( strcmp(x,"token_type")==0 ){ psp->declargslot = &(psp->gp->tokentype); psp->insertLineMacro = 0; @@ -2795,6 +2855,7 @@ void Parse(struct lemon *gp) filebuf = (char *)malloc( filesize+1 ); if( filesize>100000000 || filebuf==0 ){ ErrorMsg(ps.filename,0,"Input file too large."); + free(filebuf); gp->errorcnt++; fclose(fp); return; @@ -2986,13 +3047,28 @@ PRIVATE char *file_makename(struct lemon *lemp, const char *suffix) { char *name; char *cp; + char *filename = lemp->filename; + int sz; - name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 ); + if( outputDir ){ + cp = strrchr(filename, '/'); + if( cp ) filename = cp + 1; + } + sz = lemonStrlen(filename); + sz += lemonStrlen(suffix); + if( outputDir ) sz += lemonStrlen(outputDir) + 1; + sz += 5; + name = (char*)malloc( sz ); if( name==0 ){ fprintf(stderr,"Can't allocate space for a filename.\n"); exit(1); } - lemon_strcpy(name,lemp->filename); + name[0] = 0; + if( outputDir ){ + lemon_strcpy(name, outputDir); + lemon_strcat(name, "/"); + } + lemon_strcat(name,filename); cp = strrchr(name,'.'); if( cp ) *cp = 0; lemon_strcat(name,suffix); @@ -3020,6 +3096,27 @@ PRIVATE FILE *file_open( return fp; } +/* Print the text of a rule +*/ +void rule_print(FILE *out, struct rule *rp){ + int i, j; + fprintf(out, "%s",rp->lhs->name); + /* if( rp->lhsalias ) fprintf(out,"(%s)",rp->lhsalias); */ + fprintf(out," ::="); + for(i=0; inrhs; i++){ + struct symbol *sp = rp->rhs[i]; + if( sp->type==MULTITERMINAL ){ + fprintf(out," %s", sp->subsym[0]->name); + for(j=1; jnsubsym; j++){ + fprintf(out,"|%s", sp->subsym[j]->name); + } + }else{ + fprintf(out," %s", sp->name); + } + /* if( rp->rhsalias[i] ) fprintf(out,"(%s)",rp->rhsalias[i]); */ + } +} + /* Duplicate the input file without comments and without actions ** on rules */ void Reprint(struct lemon *lemp) @@ -3047,21 +3144,7 @@ void Reprint(struct lemon *lemp) printf("\n"); } for(rp=lemp->rule; rp; rp=rp->next){ - printf("%s",rp->lhs->name); - /* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ - printf(" ::="); - for(i=0; inrhs; i++){ - sp = rp->rhs[i]; - if( sp->type==MULTITERMINAL ){ - printf(" %s", sp->subsym[0]->name); - for(j=1; jnsubsym; j++){ - printf("|%s", sp->subsym[j]->name); - } - }else{ - printf(" %s", sp->name); - } - /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ - } + rule_print(stdout, rp); printf("."); if( rp->precsym ) printf(" [%s]",rp->precsym->name); /* if( rp->code ) printf("\n %s",rp->code); */ @@ -3203,10 +3286,11 @@ int PrintAction( /* Generate the "*.out" log file */ void ReportOutput(struct lemon *lemp) { - int i; + int i, n; struct state *stp; struct config *cfp; struct action *ap; + struct rule *rp; FILE *fp; fp = file_open(lemp,".out","wb"); @@ -3242,6 +3326,7 @@ void ReportOutput(struct lemon *lemp) } fprintf(fp, "----------------------------------------------------\n"); fprintf(fp, "Symbols:\n"); + fprintf(fp, "The first-set of non-terminals is shown after the name.\n\n"); for(i=0; insymbol; i++){ int j; struct symbol *sp; @@ -3259,8 +3344,41 @@ void ReportOutput(struct lemon *lemp) } } } + if( sp->prec>=0 ) fprintf(fp," (precedence=%d)", sp->prec); fprintf(fp, "\n"); } + fprintf(fp, "----------------------------------------------------\n"); + fprintf(fp, "Syntax-only Symbols:\n"); + fprintf(fp, "The following symbols never carry semantic content.\n\n"); + for(i=n=0; insymbol; i++){ + int w; + struct symbol *sp = lemp->symbols[i]; + if( sp->bContent ) continue; + w = (int)strlen(sp->name); + if( n>0 && n+w>75 ){ + fprintf(fp,"\n"); + n = 0; + } + if( n>0 ){ + fprintf(fp, " "); + n++; + } + fprintf(fp, "%s", sp->name); + n += w; + } + if( n>0 ) fprintf(fp, "\n"); + fprintf(fp, "----------------------------------------------------\n"); + fprintf(fp, "Rules:\n"); + for(rp=lemp->rule; rp; rp=rp->next){ + fprintf(fp, "%4d: ", rp->iRule); + rule_print(fp, rp); + fprintf(fp,"."); + if( rp->precsym ){ + fprintf(fp," [%s precedence=%d]", + rp->precsym->name, rp->precsym->prec); + } + fprintf(fp,"\n"); + } fclose(fp); return; } @@ -3321,16 +3439,19 @@ PRIVATE int compute_action(struct lemon *lemp, struct action *ap) switch( ap->type ){ case SHIFT: act = ap->x.stp->statenum; break; case SHIFTREDUCE: { - act = ap->x.rp->iRule + lemp->nstate; /* Since a SHIFT is inherient after a prior REDUCE, convert any ** SHIFTREDUCE action with a nonterminal on the LHS into a simple ** REDUCE action: */ - if( ap->sp->index>=lemp->nterminal ) act += lemp->nrule; + if( ap->sp->index>=lemp->nterminal ){ + act = lemp->minReduce + ap->x.rp->iRule; + }else{ + act = lemp->minShiftReduce + ap->x.rp->iRule; + } break; } - case REDUCE: act = ap->x.rp->iRule + lemp->nstate+lemp->nrule; break; - case ERROR: act = lemp->nstate + lemp->nrule*2; break; - case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break; + case REDUCE: act = lemp->minReduce + ap->x.rp->iRule; break; + case ERROR: act = lemp->errAction; break; + case ACCEPT: act = lemp->accAction; break; default: act = -1; break; } return act; @@ -3930,7 +4051,7 @@ void print_stack_union( fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; free(types[i]); } - if( lemp->errsym->useCnt ){ + if( lemp->errsym && lemp->errsym->useCnt ){ fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; } free(stddt); @@ -4038,6 +4159,13 @@ void ReportTable( int mnNtOfst, mxNtOfst; struct axset *ax; + lemp->minShiftReduce = lemp->nstate; + lemp->errAction = lemp->minShiftReduce + lemp->nrule; + lemp->accAction = lemp->errAction + 1; + lemp->noAction = lemp->accAction + 1; + lemp->minReduce = lemp->noAction + 1; + lemp->maxAction = lemp->minReduce + lemp->nrule; + in = tplt_open(lemp); if( in==0 ) return; out = file_open(lemp,".c","wb"); @@ -4073,10 +4201,10 @@ void ReportTable( /* Generate the defines */ fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(0, lemp->nsymbol+1, &szCodeType)); lineno++; - fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; + minimum_size_type(0, lemp->nsymbol, &szCodeType)); lineno++; + fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol); lineno++; fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(0,lemp->nstate+lemp->nrule*2+5,&szActionType)); lineno++; + minimum_size_type(0,lemp->maxAction,&szActionType)); lineno++; if( lemp->wildcard ){ fprintf(out,"#define YYWILDCARD %d\n", lemp->wildcard->index); lineno++; @@ -4099,20 +4227,40 @@ void ReportTable( while( i>=1 && (ISALNUM(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", + fprintf(out,"#define %sARG_PARAM ,%s\n",name,&lemp->arg[i]); lineno++; + fprintf(out,"#define %sARG_FETCH %s=yypParser->%s;\n", name,lemp->arg,&lemp->arg[i]); lineno++; - fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", + fprintf(out,"#define %sARG_STORE yypParser->%s=%s;\n", name,&lemp->arg[i],&lemp->arg[i]); lineno++; }else{ - fprintf(out,"#define %sARG_SDECL\n",name); lineno++; - fprintf(out,"#define %sARG_PDECL\n",name); lineno++; + fprintf(out,"#define %sARG_SDECL\n",name); lineno++; + fprintf(out,"#define %sARG_PDECL\n",name); lineno++; + fprintf(out,"#define %sARG_PARAM\n",name); lineno++; fprintf(out,"#define %sARG_FETCH\n",name); lineno++; fprintf(out,"#define %sARG_STORE\n",name); lineno++; } + if( lemp->ctx && lemp->ctx[0] ){ + i = lemonStrlen(lemp->ctx); + while( i>=1 && ISSPACE(lemp->ctx[i-1]) ) i--; + while( i>=1 && (ISALNUM(lemp->ctx[i-1]) || lemp->ctx[i-1]=='_') ) i--; + fprintf(out,"#define %sCTX_SDECL %s;\n",name,lemp->ctx); lineno++; + fprintf(out,"#define %sCTX_PDECL ,%s\n",name,lemp->ctx); lineno++; + fprintf(out,"#define %sCTX_PARAM ,%s\n",name,&lemp->ctx[i]); lineno++; + fprintf(out,"#define %sCTX_FETCH %s=yypParser->%s;\n", + name,lemp->ctx,&lemp->ctx[i]); lineno++; + fprintf(out,"#define %sCTX_STORE yypParser->%s=%s;\n", + name,&lemp->ctx[i],&lemp->ctx[i]); lineno++; + }else{ + fprintf(out,"#define %sCTX_SDECL\n",name); lineno++; + fprintf(out,"#define %sCTX_PDECL\n",name); lineno++; + fprintf(out,"#define %sCTX_PARAM\n",name); lineno++; + fprintf(out,"#define %sCTX_FETCH\n",name); lineno++; + fprintf(out,"#define %sCTX_STORE\n",name); lineno++; + } if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } - if( lemp->errsym->useCnt ){ + if( lemp->errsym && lemp->errsym->useCnt ){ fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; } @@ -4144,7 +4292,7 @@ void ReportTable( ** of placing the largest action sets first */ for(i=0; inxstate*2; i++) ax[i].iOrder = i; qsort(ax, lemp->nxstate*2, sizeof(ax[0]), axset_compare); - pActtab = acttab_alloc(); + pActtab = acttab_alloc(lemp->nsymbol, lemp->nterminal); for(i=0; inxstate*2 && ax[i].nAction>0; i++){ stp = ax[i].stp; if( ax[i].isTkn ){ @@ -4155,7 +4303,7 @@ void ReportTable( if( action<0 ) continue; acttab_action(pActtab, ap->sp->index, action); } - stp->iTknOfst = acttab_insert(pActtab); + stp->iTknOfst = acttab_insert(pActtab, 1); if( stp->iTknOfstiTknOfst; if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; }else{ @@ -4167,7 +4315,7 @@ void ReportTable( if( action<0 ) continue; acttab_action(pActtab, ap->sp->index, action); } - stp->iNtOfst = acttab_insert(pActtab); + stp->iNtOfst = acttab_insert(pActtab, 0); if( stp->iNtOfstiNtOfst; if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; } @@ -4200,16 +4348,18 @@ void ReportTable( ** been computed */ fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++; fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; + fprintf(out,"#define YYNTOKEN %d\n",lemp->nterminal); lineno++; fprintf(out,"#define YY_MAX_SHIFT %d\n",lemp->nxstate-1); lineno++; - fprintf(out,"#define YY_MIN_SHIFTREDUCE %d\n",lemp->nstate); lineno++; - i = lemp->nstate + lemp->nrule; + i = lemp->minShiftReduce; + fprintf(out,"#define YY_MIN_SHIFTREDUCE %d\n",i); lineno++; + i += lemp->nrule; fprintf(out,"#define YY_MAX_SHIFTREDUCE %d\n", i-1); lineno++; - fprintf(out,"#define YY_MIN_REDUCE %d\n", i); lineno++; - i = lemp->nstate + lemp->nrule*2; + fprintf(out,"#define YY_ERROR_ACTION %d\n", lemp->errAction); lineno++; + fprintf(out,"#define YY_ACCEPT_ACTION %d\n", lemp->accAction); lineno++; + fprintf(out,"#define YY_NO_ACTION %d\n", lemp->noAction); lineno++; + fprintf(out,"#define YY_MIN_REDUCE %d\n", lemp->minReduce); lineno++; + i = lemp->minReduce + lemp->nrule; fprintf(out,"#define YY_MAX_REDUCE %d\n", i-1); lineno++; - fprintf(out,"#define YY_ERROR_ACTION %d\n", i); lineno++; - fprintf(out,"#define YY_ACCEPT_ACTION %d\n", i+1); lineno++; - fprintf(out,"#define YY_NO_ACTION %d\n", i+2); lineno++; tplt_xfer(lemp->name,in,out,&lineno); /* Now output the action table and its associates: @@ -4225,13 +4375,13 @@ void ReportTable( */ /* Output the yy_action table */ - lemp->nactiontab = n = acttab_size(pActtab); + lemp->nactiontab = n = acttab_action_size(pActtab); lemp->tablesize += n*szActionType; fprintf(out,"#define YY_ACTTAB_COUNT (%d)\n", n); lineno++; fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; for(i=j=0; instate + lemp->nrule + 2; + if( action<0 ) action = lemp->noAction; if( j==0 ) fprintf(out," /* %5d */ ", i); fprintf(out, " %4d,", action); if( j==9 || i==n-1 ){ @@ -4244,6 +4394,7 @@ void ReportTable( fprintf(out, "};\n"); lineno++; /* Output the yy_lookahead table */ + lemp->nlookaheadtab = n = acttab_lookahead_size(pActtab); lemp->tablesize += n*szCodeType; fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; for(i=j=0; inxstate; while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", lemp->nactiontab); lineno++; fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; @@ -4288,7 +4438,6 @@ void ReportTable( fprintf(out, "};\n"); lineno++; /* Output the yy_reduce_ofst[] table */ - fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; n = lemp->nxstate; while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--; fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++; @@ -4320,7 +4469,11 @@ void ReportTable( for(i=j=0; isorted[i]; if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", stp->iDfltReduce+lemp->nstate+lemp->nrule); + if( stp->iDfltReduce<0 ){ + fprintf(out, " %4d,", lemp->errAction); + }else{ + fprintf(out, " %4d,", stp->iDfltReduce + lemp->minReduce); + } if( j==9 || i==n-1 ){ fprintf(out, "\n"); lineno++; j = 0; @@ -4354,10 +4507,8 @@ void ReportTable( */ for(i=0; insymbol; i++){ lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name); - fprintf(out," %-15s",line); - if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } + fprintf(out," /* %4d */ \"%s\",\n",i, lemp->symbols[i]->name); lineno++; } - if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); /* Generate a table containing a text string that describes every @@ -4401,7 +4552,7 @@ void ReportTable( if( sp==0 || sp->type==TERMINAL || sp->index<=0 || sp->destructor!=0 ) continue; if( once ){ - fprintf(out, " /* Default NON-TERMINAL Destructor */\n"); lineno++; + fprintf(out, " /* Default NON-TERMINAL Destructor */\n");lineno++; once = 0; } fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; @@ -4444,8 +4595,10 @@ void ReportTable( ** Note: This code depends on the fact that rules are number ** sequentually beginning with 0. */ - for(rp=lemp->rule; rp; rp=rp->next){ - fprintf(out," { %d, %d },\n",rp->lhs->index,-rp->nrhs); lineno++; + for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ + fprintf(out," { %4d, %4d }, /* (%d) ",rp->lhs->index,-rp->nrhs,i); + rule_print(out, rp); + fprintf(out," */\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); @@ -4711,7 +4864,7 @@ void ResortStates(struct lemon *lemp) for(i=0; instate; i++){ stp = lemp->sorted[i]; stp->nTknAct = stp->nNtAct = 0; - stp->iDfltReduce = lemp->nrule; /* Init dflt action to "syntax error" */ + stp->iDfltReduce = -1; /* Init dflt action to "syntax error" */ stp->iTknOfst = NO_OFFSET; stp->iNtOfst = NO_OFFSET; for(ap=stp->ap; ap; ap=ap->next){ @@ -4723,7 +4876,7 @@ void ResortStates(struct lemon *lemp) stp->nNtAct++; }else{ assert( stp->autoReduce==0 || stp->pDfltReduce==ap->x.rp ); - stp->iDfltReduce = iAction - lemp->nstate - lemp->nrule; + stp->iDfltReduce = iAction; } } } diff --git a/tool/lempar.c b/tool/lempar.c index 03e30bd164..2ebc67ee5f 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -66,19 +66,23 @@ ** zero the stack is dynamically sized using realloc() ** ParseARG_SDECL A static variable declaration for the %extra_argument ** ParseARG_PDECL A parameter declaration for the %extra_argument +** ParseARG_PARAM Code to pass %extra_argument as a subroutine parameter ** ParseARG_STORE Code to store %extra_argument into yypParser ** ParseARG_FETCH Code to extract %extra_argument from yypParser +** ParseCTX_* As ParseARG_ except for %extra_context ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** YYNSTATE the combined number of states. ** YYNRULE the number of rules in the grammar +** YYNTOKEN Number of terminal symbols ** YY_MAX_SHIFT Maximum value for shift actions ** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions ** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions -** YY_MIN_REDUCE Maximum value for reduce actions ** YY_ERROR_ACTION The yy_action[] code for syntax error ** YY_ACCEPT_ACTION The yy_action[] code for accept ** YY_NO_ACTION The yy_action[] code for no-op +** YY_MIN_REDUCE Minimum value for reduce actions +** YY_MAX_REDUCE Maximum value for reduce actions */ #ifndef INTERFACE # define INTERFACE 1 @@ -86,6 +90,7 @@ /************* Begin control #defines *****************************************/ %% /************* End control #defines *******************************************/ +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -114,9 +119,6 @@ ** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then ** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. ** -** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE -** and YY_MAX_REDUCE -** ** N == YY_ERROR_ACTION A syntax error has occurred. ** ** N == YY_ACCEPT_ACTION The parser accepts its input. @@ -124,25 +126,22 @@ ** N == YY_NO_ACTION No such action. Denotes unused ** slots in the yy_action[] table. ** +** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE +** and YY_MAX_REDUCE +** ** The action table is constructed as a single large table named yy_action[]. ** Given state S and lookahead X, the action is computed as either: ** ** (A) N = yy_action[ yy_shift_ofst[S] + X ] ** (B) N = yy_default[S] ** -** The (A) formula is preferred. The B formula is used instead if: -** (1) The yy_shift_ofst[S]+X value is out of range, or -** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or -** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT. -** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that -** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X. -** Hence only tests (1) and (2) need to be evaluated.) +** The (A) formula is preferred. The B formula is used instead if +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X. ** ** The formulas above are for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after ** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. +** the yy_shift_ofst[] array. ** ** The following are the tables generated in this section: ** @@ -215,6 +214,7 @@ struct yyParser { int yyerrcnt; /* Shifts left before out of the error */ #endif ParseARG_SDECL /* A place to hold %extra_argument */ + ParseCTX_SDECL /* A place to hold %extra_context */ #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ @@ -258,13 +258,13 @@ void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ } #endif /* NDEBUG */ -#ifndef NDEBUG +#if defined(YYCOVERAGE) || !defined(NDEBUG) /* For tracing shifts, the names of all terminals and nonterminals ** are required. The following table supplies these names */ static const char *const yyTokenName[] = { %% }; -#endif /* NDEBUG */ +#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ #ifndef NDEBUG /* For tracing reduce actions, the names of all rules are required. @@ -319,28 +319,29 @@ static int yyGrowStack(yyParser *p){ /* Initialize a new parser that has already been allocated. */ -void ParseInit(void *yypParser){ - yyParser *pParser = (yyParser*)yypParser; +void ParseInit(void *yypRawParser ParseCTX_PDECL){ + yyParser *yypParser = (yyParser*)yypRawParser; + ParseCTX_STORE #ifdef YYTRACKMAXSTACKDEPTH - pParser->yyhwm = 0; + yypParser->yyhwm = 0; #endif #if YYSTACKDEPTH<=0 - pParser->yytos = NULL; - pParser->yystack = NULL; - pParser->yystksz = 0; - if( yyGrowStack(pParser) ){ - pParser->yystack = &pParser->yystk0; - pParser->yystksz = 1; + yypParser->yytos = NULL; + yypParser->yystack = NULL; + yypParser->yystksz = 0; + if( yyGrowStack(yypParser) ){ + yypParser->yystack = &yypParser->yystk0; + yypParser->yystksz = 1; } #endif #ifndef YYNOERRORRECOVERY - pParser->yyerrcnt = -1; + yypParser->yyerrcnt = -1; #endif - pParser->yytos = pParser->yystack; - pParser->yystack[0].stateno = 0; - pParser->yystack[0].major = 0; + yypParser->yytos = yypParser->yystack; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; #if YYSTACKDEPTH>0 - pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1]; + yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; #endif } @@ -357,11 +358,14 @@ void ParseInit(void *yypParser){ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ -void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); - if( pParser ) ParseInit(pParser); - return pParser; +void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) ParseCTX_PDECL){ + yyParser *yypParser; + yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); + if( yypParser ){ + ParseCTX_STORE + ParseInit(yypParser ParseCTX_PARAM); + } + return (void*)yypParser; } #endif /* Parse_ENGINEALWAYSONSTACK */ @@ -378,7 +382,8 @@ static void yy_destructor( YYCODETYPE yymajor, /* Type code for object to destroy */ YYMINORTYPE *yypminor /* The object to be destroyed */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH switch( yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen @@ -460,24 +465,66 @@ int ParseStackPeak(void *p){ } #endif +/* This array of booleans keeps track of the parser statement +** coverage. The element yycoverage[X][Y] is set when the parser +** is in state X and has a lookahead token Y. In a well-tested +** systems, every element of this matrix should end up being set. +*/ +#if defined(YYCOVERAGE) +static unsigned char yycoverage[YYNSTATE][YYNTOKEN]; +#endif + +/* +** Write into out a description of every state/lookahead combination that +** +** (1) has not been used by the parser, and +** (2) is not a syntax error. +** +** Return the number of missed state/lookahead combinations. +*/ +#if defined(YYCOVERAGE) +int ParseCoverage(FILE *out){ + int stateno, iLookAhead, i; + int nMissed = 0; + for(stateno=0; statenoyytos->stateno; - - if( stateno>=YY_MIN_REDUCE ) return stateno; + + if( stateno>YY_MAX_SHIFT ) return stateno; assert( stateno <= YY_SHIFT_COUNT ); +#if defined(YYCOVERAGE) + yycoverage[stateno][iLookAhead] = 1; +#endif do{ i = yy_shift_ofst[stateno]; + assert( i>=0 ); + /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */ assert( iLookAhead!=YYNOCODE ); + assert( iLookAhead < YYNTOKEN ); i += iLookAhead; - if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ if( iLookAhead=YY_ACTTAB_COUNT j0 ){ #ifndef NDEBUG @@ -527,8 +575,8 @@ static unsigned int yy_find_shift_action( ** Find the appropriate action for a parser given the non-terminal ** look-ahead token iLookAhead. */ -static int yy_find_reduce_action( - int stateno, /* Current state number */ +static YYACTIONTYPE yy_find_reduce_action( + YYACTIONTYPE stateno, /* Current state number */ YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; @@ -540,7 +588,6 @@ static int yy_find_reduce_action( assert( stateno<=YY_REDUCE_COUNT ); #endif i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); assert( iLookAhead!=YYNOCODE ); i += iLookAhead; #ifdef YYERRORSYMBOL @@ -558,7 +605,8 @@ static int yy_find_reduce_action( ** The following routine is called if the stack overflows. */ static void yyStackOverflow(yyParser *yypParser){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); @@ -570,27 +618,29 @@ static void yyStackOverflow(yyParser *yypParser){ /******** Begin %stack_overflow code ******************************************/ %% /******** End %stack_overflow code ********************************************/ - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ + ParseARG_STORE /* Suppress warning about unused %extra_argument var */ + ParseCTX_STORE } /* ** Print tracing information for a SHIFT action */ #ifndef NDEBUG -static void yyTraceShift(yyParser *yypParser, int yyNewState){ +static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){ if( yyTraceFILE ){ if( yyNewStateyytos->major], + fprintf(yyTraceFILE,"%s%s '%s', go to state %d\n", + yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], yyNewState); }else{ - fprintf(yyTraceFILE,"%sShift '%s'\n", - yyTracePrompt,yyTokenName[yypParser->yytos->major]); + fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n", + yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], + yyNewState - YY_MIN_REDUCE); } } } #else -# define yyTraceShift(X,Y) +# define yyTraceShift(X,Y,Z) #endif /* @@ -598,8 +648,8 @@ static void yyTraceShift(yyParser *yypParser, int yyNewState){ */ static void yy_shift( yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ + YYACTIONTYPE yyNewState, /* The new state to shift in */ + YYCODETYPE yyMajor, /* The major token to shift in */ ParseTOKENTYPE yyMinor /* The minor token to shift in */ ){ yyStackEntry *yytos; @@ -629,10 +679,10 @@ static void yy_shift( yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; } yytos = yypParser->yytos; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; + yytos->stateno = yyNewState; + yytos->major = yyMajor; yytos->minor.yy0 = yyMinor; - yyTraceShift(yypParser, yyNewState); + yyTraceShift(yypParser, yyNewState, "Shift"); } /* The following table contains information about every rule that @@ -650,22 +700,39 @@ static void yy_accept(yyParser*); /* Forward Declaration */ /* ** Perform a reduce action and the shift that must immediately ** follow the reduce. +** +** The yyLookahead and yyLookaheadToken parameters provide reduce actions +** access to the lookahead token (if any). The yyLookahead will be YYNOCODE +** if the lookahead token has already been consumed. As this procedure is +** only called from one place, optimizing compilers will in-line it, which +** means that the extra parameters have no performance impact. */ -static void yy_reduce( +static YYACTIONTYPE yy_reduce( yyParser *yypParser, /* The parser */ - unsigned int yyruleno /* Number of the rule by which to reduce */ + unsigned int yyruleno, /* Number of the rule by which to reduce */ + int yyLookahead, /* Lookahead token, or YYNOCODE if none */ + ParseTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ + ParseCTX_PDECL /* %extra_context */ ){ int yygoto; /* The next state */ - int yyact; /* The next action */ + YYACTIONTYPE yyact; /* The next action */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; + ParseARG_FETCH + (void)yyLookahead; + (void)yyLookaheadToken; yymsp = yypParser->yytos; #ifndef NDEBUG if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ yysize = yyRuleInfo[yyruleno].nrhs; - fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt, - yyRuleName[yyruleno], yymsp[yysize].stateno); + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s].\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno]); + } } #endif /* NDEBUG */ @@ -682,13 +749,19 @@ static void yy_reduce( #if YYSTACKDEPTH>0 if( yypParser->yytos>=yypParser->yystackEnd ){ yyStackOverflow(yypParser); - return; + /* The call to yyStackOverflow() above pops the stack until it is + ** empty, causing the main parser loop to exit. So the return value + ** is never used and does not matter. */ + return 0; } #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); - return; + /* The call to yyStackOverflow() above pops the stack until it is + ** empty, causing the main parser loop to exit. So the return value + ** is never used and does not matter. */ + return 0; } yymsp = yypParser->yytos; } @@ -720,16 +793,12 @@ static void yy_reduce( /* It is not possible for a REDUCE to be followed by an error */ assert( yyact!=YY_ERROR_ACTION ); - if( yyact==YY_ACCEPT_ACTION ){ - yypParser->yytos += yysize; - yy_accept(yypParser); - }else{ - yymsp += yysize+1; - yypParser->yytos = yymsp; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yyTraceShift(yypParser, yyact); - } + yymsp += yysize+1; + yypParser->yytos = yymsp; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yyTraceShift(yypParser, yyact, "... then shift"); + return yyact; } /* @@ -739,7 +808,8 @@ static void yy_reduce( static void yy_parse_failed( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); @@ -751,7 +821,8 @@ static void yy_parse_failed( /************ Begin %parse_failure code ***************************************/ %% /************ End %parse_failure code *****************************************/ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } #endif /* YYNOERRORRECOVERY */ @@ -763,12 +834,14 @@ static void yy_syntax_error( int yymajor, /* The major type of the error token */ ParseTOKENTYPE yyminor /* The minor type of the error token */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #define TOKEN yyminor /************ Begin %syntax_error code ****************************************/ %% /************ End %syntax_error code ******************************************/ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } /* @@ -777,7 +850,8 @@ static void yy_syntax_error( static void yy_accept( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH; + ParseARG_FETCH + ParseCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); @@ -792,7 +866,8 @@ static void yy_accept( /*********** Begin %parse_accept code *****************************************/ %% /*********** End %parse_accept code *******************************************/ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ + ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ + ParseCTX_STORE } /* The main parser program. @@ -821,38 +896,51 @@ void Parse( ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; - unsigned int yyact; /* The parser action. */ + YYACTIONTYPE yyact; /* The parser action. */ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) int yyendofinput; /* True if we are at the end of input */ #endif #ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif - yyParser *yypParser; /* The parser */ + yyParser *yypParser = (yyParser*)yyp; /* The parser */ + ParseCTX_FETCH + ParseARG_STORE - yypParser = (yyParser*)yyp; assert( yypParser->yytos!=0 ); #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) yyendofinput = (yymajor==0); #endif - ParseARG_STORE; + yyact = yypParser->yytos->stateno; #ifndef NDEBUG if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]); + if( yyact < YY_MIN_REDUCE ){ + fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact); + }else{ + fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); + } } #endif do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyact <= YY_MAX_SHIFTREDUCE ){ - yy_shift(yypParser,yyact,yymajor,yyminor); + assert( yyact==yypParser->yytos->stateno ); + yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); + if( yyact >= YY_MIN_REDUCE ){ + yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, + yyminor ParseCTX_PARAM); + }else if( yyact <= YY_MAX_SHIFTREDUCE ){ + yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; #endif - yymajor = YYNOCODE; - }else if( yyact <= YY_MAX_REDUCE ){ - yy_reduce(yypParser,yyact-YY_MIN_REDUCE); + break; + }else if( yyact==YY_ACCEPT_ACTION ){ + yypParser->yytos--; + yy_accept(yypParser); + return; }else{ assert( yyact == YY_ERROR_ACTION ); yyminorunion.yy0 = yyminor; @@ -919,6 +1007,8 @@ void Parse( } yypParser->yyerrcnt = 3; yyerrorhit = 1; + if( yymajor==YYNOCODE ) break; + yyact = yypParser->yytos->stateno; #elif defined(YYNOERRORRECOVERY) /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to ** do any kind of error recovery. Instead, simply invoke the syntax @@ -929,8 +1019,7 @@ void Parse( */ yy_syntax_error(yypParser,yymajor, yyminor); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - + break; #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** @@ -952,10 +1041,10 @@ void Parse( yypParser->yyerrcnt = -1; #endif } - yymajor = YYNOCODE; + break; #endif } - }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); + }while( yypParser->yytos>yypParser->yystack ); #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -970,3 +1059,18 @@ void Parse( #endif return; } + +/* +** Return the fallback token corresponding to canonical token iToken, or +** 0 if iToken has no fallback. +*/ +int ParseFallback(int iToken){ +#ifdef YYFALLBACK + if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){ + return yyFallback[iToken]; + } +#else + (void)iToken; +#endif + return 0; +} diff --git a/tool/mkautoconfamal.sh b/tool/mkautoconfamal.sh index 4864ee85c3..7cd7da35f6 100644 --- a/tool/mkautoconfamal.sh +++ b/tool/mkautoconfamal.sh @@ -51,7 +51,7 @@ cp sqlite3.h $TMPSPACE cp sqlite3ext.h $TMPSPACE cp $TOP/sqlite3.1 $TMPSPACE cp $TOP/sqlite3.pc.in $TMPSPACE -cp $TOP/src/shell.c $TMPSPACE +cp shell.c $TMPSPACE cp $TOP/src/sqlite3.rc $TMPSPACE cp $TOP/tool/Replace.cs $TMPSPACE diff --git a/tool/mkccode.tcl b/tool/mkccode.tcl new file mode 100755 index 0000000000..41b09f1e81 --- /dev/null +++ b/tool/mkccode.tcl @@ -0,0 +1,93 @@ +#!/usr/bin/tclsh +# +# Use this script to build C-language source code for a program that uses +# tclsqlite.c together with custom TCL scripts and/or C extensions for +# either SQLite or TCL. +# +# Usage example: +# +# tclsh mktclsqliteprog.tcl demoapp.c.in >demoapp.c +# +# The demoapp.c.in file contains a mixture of C code, TCL script, and +# processing directives used by mktclsqliteprog.tcl to build the final C-code +# output file. Most lines of demoapp.c.in are copied straight through into +# the output. The following control directives are recognized: +# +# BEGIN_STRING +# +# This marks the beginning of large string literal - usually a TCL +# script of some kind. Subsequent lines of text through the first +# line that begins with END_STRING are converted into a C-language +# string literal. +# +# INCLUDE path +# +# The path argument is the name of a file to be inserted in place of +# the INCLUDE line. The path can begin with $ROOT to signify the +# root of the SQLite source tree, or $HOME to signify the directory +# that contains the demoapp.c.in input script itself. If the path does +# not begin with either $ROOT or $HOME, then it is interpreted relative +# to the current working directory. +# +# If the INCLUDE occurs in the middle of BEGIN_STRING...END_STRING +# then all of the text in the input file is converted into C-language +# string literals. +# +# None of the control directives described above will nest. Only the +# top-level input file ("demoapp.c.in" in the example) is interpreted. +# referenced files are copied verbatim. +# +if {[llength $argv]!=1} { + puts stderr "Usage: $argv0 TEMPLATE >OUTPUT" + exit 1 +} +set infile [lindex $argv 0] +set ROOT [file normalize [file dir $argv0]/..] +set HOME [file normalize [file dir $infile]] +set in [open $infile rb] +puts [subst {/* DO NOT EDIT +** +** This file was generated by \"$argv0 $infile\". +** To make changes, edit $infile then rerun the generator +** command. +*/}] +set instr 0 +while {1} { + set line [gets $in] + if {[eof $in]} break + if {[regexp {^INCLUDE (.*)} $line all path]} { + regsub {^\$ROOT\y} $path $ROOT path + regsub {^\$HOME\y} $path $HOME path + set in2 [open $path rb] + puts "/* INCLUDE $path */" + if {$instr} { + while {1} { + set line [gets $in2] + if {[eof $in2]} break + set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line] + puts "\"$x\\n\"" + } + } else { + puts [read $in2] + } + puts "/* END $path */" + close $in2 + continue + } + if {[regexp {^BEGIN_STRING} $line]} { + set instr 1 + puts "/* BEGIN_STRING */" + continue + } + if {[regexp {^END_STRING} $line]} { + set instr 0 + puts "/* END_STRING */" + continue + } + if {$instr} { + set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line] + puts "\"$x\\n\"" + } else { + puts $line + } +} diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index 42112718da..7ef4cbb6ae 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -143,6 +143,16 @@ struct Keyword { #else # define CTE 0x00040000 #endif +#ifdef SQLITE_OMIT_UPSERT +# define UPSERT 0 +#else +# define UPSERT 0x00080000 +#endif +#ifdef SQLITE_OMIT_WINDOWFUNC +# define WINDOWFUNC 0 +#else +# define WINDOWFUNC 0x00100000 +#endif /* ** These are the keywords @@ -175,6 +185,7 @@ static Keyword aKeywordTable[] = { { "CONSTRAINT", "TK_CONSTRAINT", ALWAYS }, { "CREATE", "TK_CREATE", ALWAYS }, { "CROSS", "TK_JOIN_KW", ALWAYS }, + { "CURRENT", "TK_CURRENT", WINDOWFUNC }, { "CURRENT_DATE", "TK_CTIME_KW", ALWAYS }, { "CURRENT_TIME", "TK_CTIME_KW", ALWAYS }, { "CURRENT_TIMESTAMP","TK_CTIME_KW", ALWAYS }, @@ -186,6 +197,7 @@ static Keyword aKeywordTable[] = { { "DESC", "TK_DESC", ALWAYS }, { "DETACH", "TK_DETACH", ATTACH }, { "DISTINCT", "TK_DISTINCT", ALWAYS }, + { "DO", "TK_DO", UPSERT }, { "DROP", "TK_DROP", ALWAYS }, { "END", "TK_END", ALWAYS }, { "EACH", "TK_EACH", TRIGGER }, @@ -196,6 +208,8 @@ static Keyword aKeywordTable[] = { { "EXISTS", "TK_EXISTS", ALWAYS }, { "EXPLAIN", "TK_EXPLAIN", EXPLAIN }, { "FAIL", "TK_FAIL", CONFLICT|TRIGGER }, + { "FILTER", "TK_FILTER", WINDOWFUNC }, + { "FOLLOWING", "TK_FOLLOWING", WINDOWFUNC }, { "FOR", "TK_FOR", TRIGGER }, { "FOREIGN", "TK_FOREIGN", FKEY }, { "FROM", "TK_FROM", ALWAYS }, @@ -226,6 +240,7 @@ static Keyword aKeywordTable[] = { { "NATURAL", "TK_JOIN_KW", ALWAYS }, { "NO", "TK_NO", FKEY }, { "NOT", "TK_NOT", ALWAYS }, + { "NOTHING", "TK_NOTHING", UPSERT }, { "NOTNULL", "TK_NOTNULL", ALWAYS }, { "NULL", "TK_NULL", ALWAYS }, { "OF", "TK_OF", ALWAYS }, @@ -234,11 +249,15 @@ static Keyword aKeywordTable[] = { { "OR", "TK_OR", ALWAYS }, { "ORDER", "TK_ORDER", ALWAYS }, { "OUTER", "TK_JOIN_KW", ALWAYS }, + { "OVER", "TK_OVER", WINDOWFUNC }, + { "PARTITION", "TK_PARTITION", WINDOWFUNC }, { "PLAN", "TK_PLAN", EXPLAIN }, { "PRAGMA", "TK_PRAGMA", PRAGMA }, + { "PRECEDING", "TK_PRECEDING", WINDOWFUNC }, { "PRIMARY", "TK_PRIMARY", ALWAYS }, { "QUERY", "TK_QUERY", EXPLAIN }, { "RAISE", "TK_RAISE", TRIGGER }, + { "RANGE", "TK_RANGE", WINDOWFUNC }, { "RECURSIVE", "TK_RECURSIVE", CTE }, { "REFERENCES", "TK_REFERENCES", FKEY }, { "REGEXP", "TK_LIKE_KW", ALWAYS }, @@ -250,6 +269,7 @@ static Keyword aKeywordTable[] = { { "RIGHT", "TK_JOIN_KW", ALWAYS }, { "ROLLBACK", "TK_ROLLBACK", ALWAYS }, { "ROW", "TK_ROW", TRIGGER }, + { "ROWS", "TK_ROWS", ALWAYS }, { "SAVEPOINT", "TK_SAVEPOINT", ALWAYS }, { "SELECT", "TK_SELECT", ALWAYS }, { "SET", "TK_SET", ALWAYS }, @@ -260,6 +280,7 @@ static Keyword aKeywordTable[] = { { "TO", "TK_TO", ALWAYS }, { "TRANSACTION", "TK_TRANSACTION", ALWAYS }, { "TRIGGER", "TK_TRIGGER", TRIGGER }, + { "UNBOUNDED", "TK_UNBOUNDED", WINDOWFUNC }, { "UNION", "TK_UNION", COMPOUND }, { "UNIQUE", "TK_UNIQUE", ALWAYS }, { "UPDATE", "TK_UPDATE", ALWAYS }, @@ -268,6 +289,7 @@ static Keyword aKeywordTable[] = { { "VALUES", "TK_VALUES", ALWAYS }, { "VIEW", "TK_VIEW", VIEW }, { "VIRTUAL", "TK_VIRTUAL", VTAB }, + { "WINDOW", "TK_WINDOW", WINDOWFUNC }, { "WITH", "TK_WITH", CTE }, { "WITHOUT", "TK_WITHOUT", ALWAYS }, { "WHEN", "TK_WHEN", ALWAYS }, @@ -610,6 +632,16 @@ int main(int argc, char **argv){ printf(" return id;\n"); printf("}\n"); printf("#define SQLITE_N_KEYWORD %d\n", nKeyword); + printf("int sqlite3_keyword_name(int i,const char **pzName,int *pnName){\n"); + printf(" if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR;\n"); + printf(" *pzName = zKWText + aKWOffset[i];\n"); + printf(" *pnName = aKWLen[i];\n"); + printf(" return SQLITE_OK;\n"); + printf("}\n"); + printf("int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; }\n"); + printf("int sqlite3_keyword_check(const char *zName, int nName){\n"); + printf(" return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName);\n"); + printf("}\n"); return 0; } diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index 8d5729865c..764641faee 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -54,7 +54,7 @@ proc substVars { data } { set blocks(1) [string trimleft [string map [list \\\\ \\] { _HASHCHAR=^# !IF ![echo !IFNDEF VERSION > rcver.vc] && \\ - ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \\ + ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| "%SystemRoot%\System32\find.exe" "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \\ ![echo !ENDIF >> rcver.vc] !INCLUDE rcver.vc !ENDIF @@ -83,7 +83,7 @@ Replace.exe: sqlite3.def: Replace.exe $(LIBOBJ) echo EXPORTS > sqlite3.def dumpbin /all $(LIBOBJ) \\ - | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\ + | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\ | sort >> sqlite3.def }]] diff --git a/tool/mkopcodeh.tcl b/tool/mkopcodeh.tcl index a12d1901ee..57017364a0 100644 --- a/tool/mkopcodeh.tcl +++ b/tool/mkopcodeh.tcl @@ -24,7 +24,7 @@ # # This script also scans for lines of the form: # -# case OP_aaaa: /* jump, in1, in2, in3, out2-prerelease, out3 */ +# case OP_aaaa: /* jump, in1, in2, in3, out2, out3 */ # # When such comments are found on an opcode, it means that certain # properties apply to that opcode. Set corresponding flags using the @@ -33,7 +33,9 @@ set in stdin set currentOp {} +set prevName {} set nOp 0 +set nGroup 0 while {![eof $in]} { set line [gets $in] @@ -75,7 +77,9 @@ while {![eof $in]} { if {[regexp {^case OP_} $line]} { set line [split $line] set name [string trim [lindex $line 1] :] + if {$name=="OP_Abortable"} continue; # put OP_Abortable last set op($name) -1 + set group($name) 0 set jump($name) 0 set in1($name) 0 set in2($name) 0 @@ -96,15 +100,31 @@ while {![eof $in]} { set def($val) $name } } - jump {set jump($name) 1} - in1 {set in1($name) 1} - in2 {set in2($name) 1} - in3 {set in3($name) 1} - out2 {set out2($name) 1} - out3 {set out3($name) 1} + group {set group($name) 1} + jump {set jump($name) 1} + in1 {set in1($name) 1} + in2 {set in2($name) 1} + in3 {set in3($name) 1} + out2 {set out2($name) 1} + out3 {set out3($name) 1} } } + if {$group($name)} { + set newGroup 0 + if {[info exists groups($nGroup)]} { + if {$prevName=="" || !$group($prevName)} { + set newGroup 1 + } + } + lappend groups($nGroup) $name + if {$newGroup} {incr nGroup} + } else { + if {$prevName!="" && $group($prevName)} { + incr nGroup + } + } set order($nOp) $name + set prevName $name incr nOp } } @@ -113,7 +133,7 @@ while {![eof $in]} { # puts "/* Automatically generated. Do not edit */" puts "/* See the tool/mkopcodeh.tcl script for details */" -foreach name {OP_Noop OP_Explain} { +foreach name {OP_Noop OP_Explain OP_Abortable} { set jump($name) 0 set in1($name) 0 set in2($name) 0 @@ -180,8 +200,39 @@ for {set i 0} {$i<$nOp} {incr i} { } -# Generate the numeric values for all remaining opcodes +# Generate the numeric values for all remaining opcodes, while +# preserving any groupings of opcodes (i.e. those that must be +# together). # +for {set g 0} {$g<$nGroup} {incr g} { + set gLen [llength $groups($g)] + set ok 0; set start -1 + while {!$ok} { + set seek $cnt; incr seek + while {[info exists used($seek)]} {incr seek} + set ok 1; set start $seek + for {set j 0} {$j<$gLen} {incr j} { + incr seek + if {[info exists used($seek)]} { + set ok 0; break + } + } + } + if {$ok} { + set next $start + for {set j 0} {$j<$gLen} {incr j} { + set name [lindex $groups($g) $j] + if {$op($name)>=0} continue + set op($name) $next + set used($next) 1 + set def($next) $name + incr next + } + } else { + error "cannot find opcodes for group: $groups($g)" + } +} + for {set i 0} {$i<$nOp} {incr i} { set name $order($i) if {$op($name)<0} { @@ -202,7 +253,7 @@ for {set i 0} {$i<=$max} {incr i} { set name $def($i) puts -nonewline [format {#define %-16s %3d} $name $i] set com {} - if {$jump($name)} { + if {[info exists jump($name)] && $jump($name)} { lappend com "jump" } if {[info exists sameas($i)]} { diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl index e3ddcb9eeb..88f645bbe3 100644 --- a/tool/mkopts.tcl +++ b/tool/mkopts.tcl @@ -11,7 +11,7 @@ while {![eof stdin]} { if {$line==""} continue regsub -all "\[ \t\n,\]+" [string trim $line] { } line foreach token [split $line { }] { - if {![regexp {(([a-zA-Z]+)_)?([_a-zA-Z]+)} $token all px p2 name]} continue + if {![regexp {(([a-zA-Z]+)_)?([_a-zA-Z0-9]+)} $token all px p2 name]} continue lappend namelist [string tolower $name] if {$px!=""} {set prefix $p2} } @@ -23,7 +23,7 @@ proc put_item x { global col if {$col==0} {puts -nonewline " "} if {$col<2} { - puts -nonewline [format " %-21s" $x] + puts -nonewline [format " %-25s" $x] incr col } else { puts $x diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 1bfbeb7c58..c40e3f5b77 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -220,9 +220,17 @@ set pragma_def { NAME: table_info FLAG: NeedSchema Result1 SchemaOpt + ARG: 0 COLS: cid name type notnull dflt_value pk IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + NAME: table_xinfo + TYPE: TABLE_INFO + FLAG: NeedSchema Result1 SchemaOpt + ARG: 1 + COLS: cid name type notnull dflt_value pk hidden + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + NAME: stats FLAG: NeedSchema Result0 SchemaReq COLS: tbl idx wdth hght flgs @@ -382,6 +390,11 @@ set pragma_def { NAME: optimize FLAG: Result1 NeedSchema + + NAME: legacy_alter_table + TYPE: FLAG + ARG: SQLITE_LegacyAlter + IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) } # Open the output file @@ -405,20 +418,20 @@ set cols {} set cols_list {} set arg 0 proc record_one {} { - global name type if arg allbyname typebyif flags cols allcols + global name type if arg allbyname typebyif flags cols all_cols global cols_list colUsedBy if {$name==""} return if {$cols!=""} { - if {![info exists allcols($cols)]} { + if {![info exists all_cols($cols)]} { + set all_cols($cols) 1 lappend cols_list $cols - set allcols($cols) [llength $cols_list] } - set cx $allcols($cols) + set cx $cols lappend colUsedBy($cols) $name } else { set cx 0 } - set allbyname($name) [list $type $arg $if $flags $cx] + set allbyname($name) [list $type $arg $if $flags $cols] set name {} set type {} set if {} @@ -500,6 +513,13 @@ foreach f [lsort [array names allflags]] { set fv [expr {$fv*2}] } +# Sort the column lists so that longer column lists occur first +# +proc colscmp {a b} { + return [expr {[llength $b] - [llength $a]}] +} +set cols_list [lsort -command colscmp $cols_list] + # Generate the array of column names used by pragmas that act like # queries. # @@ -508,10 +528,23 @@ puts $fd "** or that return single-column results where the name of the" puts $fd "** result column is different from the name of the pragma\n*/" puts $fd "static const char *const pragCName\[\] = {" set offset 0 +set allcollist {} foreach cols $cols_list { - set cols_offset($allcols($cols)) $offset + set n [llength $cols] + set limit [expr {[llength $allcollist] - $n}] + for {set i 0} {$i<$limit} {incr i} { + set sublist [lrange $allcollist $i [expr {$i+$n-1}]] + if {$sublist==$cols} { + puts $fd [format "%27s/* $colUsedBy($cols) reuses $i */" ""] + set cols_offset($cols) $i + break + } + } + if {$i<$limit} continue + set cols_offset($cols) $offset set ub " /* Used by: $colUsedBy($cols) */" foreach c $cols { + lappend allcollist $c puts $fd [format " /* %3d */ %-14s%s" $offset \"$c\", $ub] set ub "" incr offset @@ -537,12 +570,12 @@ set current_if {} set spacer [format { %26s } {}] foreach name $allnames { foreach {type arg if flag cx} $allbyname($name) break - if {$cx==0} { + if {$cx==0 || $cx==""} { set cy 0 set nx 0 } else { set cy $cols_offset($cx) - set nx [llength [lindex $cols_list [expr {$cx-1}]]] + set nx [llength $cx] } if {$if!=$current_if} { if {$current_if!=""} { diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index ce75234ce9..534ac6156a 100644 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -1,11 +1,16 @@ #!/usr/bin/tclsh # -# Run this script to generate the "src/shell.c" source file from +# Run this script to generate the "shell.c" source file from # constituent parts. # +# No arguments are required. This script determines the location +# of its input files relative to the location of the script itself. +# This script should be tool/mkshellc.tcl. If the directory holding +# the script is $DIR, then the component parts are located in $DIR/../src +# and $DIR/../ext/misc. +# set topdir [file dir [file dir [file normal $argv0]]] -puts "Overwriting $topdir/src/shell.c with new shell source code..." -set out [open $topdir/src/shell.c wb] +set out stdout puts $out {/* DO NOT EDIT! ** This file is automatically generated by the script in the canonical ** SQLite source tree at tool/mkshellc.tcl. That script combines source @@ -25,15 +30,30 @@ puts $out {/* DO NOT EDIT! ** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script. */} set in [open $topdir/src/shell.c.in rb] -while {![eof $in]} { - set lx [gets $in] +proc omit_redundant_typedefs {line} { + global typedef_seen + if {[regexp {^typedef .*;} $line]} { + if {[info exists typedef_seen($line)]} { + return "/* $line */" + } + set typedef_seen($line) 1 + } + return $line +} +while {1} { + set lx [omit_redundant_typedefs [gets $in]] + if {[eof $in]} break; if {[regexp {^INCLUDE } $lx]} { set cfile [lindex $lx 1] puts $out "/************************* Begin $cfile ******************/" set in2 [open $topdir/src/$cfile rb] while {![eof $in2]} { - set lx [gets $in2] + set lx [omit_redundant_typedefs [gets $in2]] if {[regexp {^#include "sqlite} $lx]} continue + if {[regexp {^# *include "test_windirent.h"} $lx]} { + set lx "/* $lx */" + } + set lx [string map [list __declspec(dllexport) {}] $lx] puts $out $lx } close $in2 diff --git a/tool/mksourceid.c b/tool/mksourceid.c new file mode 100644 index 0000000000..282f5c4414 --- /dev/null +++ b/tool/mksourceid.c @@ -0,0 +1,853 @@ +/* +** Run this program with a single argument which is the name of the +** Fossil "manifest" file for a project, and this program will emit on +** standard output the "source id" for for the program. +** +** (1) The "source id" is the date of check-in together with the +** SHA3 hash of the manifest file. +** +** (2) All individual file hashes in the manifest are verified. If any +** source file has changed, the SHA3 hash ends with "modified". +** +*/ +#include +#include +#include +#include +#include + +/* Portable 64-bit unsigned integers */ +#if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 u64; +#else + typedef unsigned long long int u64; +#endif + + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DBYTEORDER=0 is set, then byte-order is determined +** at run-time. +*/ +#ifndef BYTEORDER +# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) +# define BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) +# define BYTEORDER 4321 +# else +# define BYTEORDER 0 +# endif +#endif + + + +/* +** State structure for a SHA3 hash in progress +*/ +typedef struct SHA3Context SHA3Context; +struct SHA3Context { + union { + u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ + unsigned char x[1600]; /* ... or 1600 bytes */ + } u; + unsigned nRate; /* Bytes of input accepted per Keccak iteration */ + unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ + unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ +}; + +/* +** A single step of the Keccak mixing function for a 1600-bit state +*/ +static void KeccakF1600Step(SHA3Context *p){ + int i; + u64 B0, B1, B2, B3, B4; + u64 C0, C1, C2, C3, C4; + u64 D0, D1, D2, D3, D4; + static const u64 RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, + 0x800000000000808aULL, 0x8000000080008000ULL, + 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008aULL, 0x0000000000000088ULL, + 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, + 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, + 0x0000000080000001ULL, 0x8000000080008008ULL + }; +# define A00 (p->u.s[0]) +# define A01 (p->u.s[1]) +# define A02 (p->u.s[2]) +# define A03 (p->u.s[3]) +# define A04 (p->u.s[4]) +# define A10 (p->u.s[5]) +# define A11 (p->u.s[6]) +# define A12 (p->u.s[7]) +# define A13 (p->u.s[8]) +# define A14 (p->u.s[9]) +# define A20 (p->u.s[10]) +# define A21 (p->u.s[11]) +# define A22 (p->u.s[12]) +# define A23 (p->u.s[13]) +# define A24 (p->u.s[14]) +# define A30 (p->u.s[15]) +# define A31 (p->u.s[16]) +# define A32 (p->u.s[17]) +# define A33 (p->u.s[18]) +# define A34 (p->u.s[19]) +# define A40 (p->u.s[20]) +# define A41 (p->u.s[21]) +# define A42 (p->u.s[22]) +# define A43 (p->u.s[23]) +# define A44 (p->u.s[24]) +# define ROL64(a,x) ((a<>(64-x))) + + for(i=0; i<24; i+=4){ + C0 = A00^A10^A20^A30^A40; + C1 = A01^A11^A21^A31^A41; + C2 = A02^A12^A22^A32^A42; + C3 = A03^A13^A23^A33^A43; + C4 = A04^A14^A24^A34^A44; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A11^D1), 44); + B2 = ROL64((A22^D2), 43); + B3 = ROL64((A33^D3), 21); + B4 = ROL64((A44^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i]; + A11 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A20^D0), 3); + B3 = ROL64((A31^D1), 45); + B4 = ROL64((A42^D2), 61); + B0 = ROL64((A03^D3), 28); + B1 = ROL64((A14^D4), 20); + A20 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A40^D0), 18); + B0 = ROL64((A01^D1), 1); + B1 = ROL64((A12^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A34^D4), 8); + A40 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A10^D0), 36); + B2 = ROL64((A21^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A43^D3), 56); + B0 = ROL64((A04^D4), 27); + A10 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A30^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A02^D2), 62); + B1 = ROL64((A13^D3), 55); + B2 = ROL64((A24^D4), 39); + A30 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + C0 = A00^A20^A40^A10^A30; + C1 = A11^A31^A01^A21^A41; + C2 = A22^A42^A12^A32^A02; + C3 = A33^A03^A23^A43^A13; + C4 = A44^A14^A34^A04^A24; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A31^D1), 44); + B2 = ROL64((A12^D2), 43); + B3 = ROL64((A43^D3), 21); + B4 = ROL64((A24^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+1]; + A31 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A40^D0), 3); + B3 = ROL64((A21^D1), 45); + B4 = ROL64((A02^D2), 61); + B0 = ROL64((A33^D3), 28); + B1 = ROL64((A14^D4), 20); + A40 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A30^D0), 18); + B0 = ROL64((A11^D1), 1); + B1 = ROL64((A42^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A04^D4), 8); + A30 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A20^D0), 36); + B2 = ROL64((A01^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A13^D3), 56); + B0 = ROL64((A44^D4), 27); + A20 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A10^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A22^D2), 62); + B1 = ROL64((A03^D3), 55); + B2 = ROL64((A34^D4), 39); + A10 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + C0 = A00^A40^A30^A20^A10; + C1 = A31^A21^A11^A01^A41; + C2 = A12^A02^A42^A32^A22; + C3 = A43^A33^A23^A13^A03; + C4 = A24^A14^A04^A44^A34; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A21^D1), 44); + B2 = ROL64((A42^D2), 43); + B3 = ROL64((A13^D3), 21); + B4 = ROL64((A34^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+2]; + A21 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A30^D0), 3); + B3 = ROL64((A01^D1), 45); + B4 = ROL64((A22^D2), 61); + B0 = ROL64((A43^D3), 28); + B1 = ROL64((A14^D4), 20); + A30 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A10^D0), 18); + B0 = ROL64((A31^D1), 1); + B1 = ROL64((A02^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A44^D4), 8); + A10 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A40^D0), 36); + B2 = ROL64((A11^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A03^D3), 56); + B0 = ROL64((A24^D4), 27); + A40 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A20^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A12^D2), 62); + B1 = ROL64((A33^D3), 55); + B2 = ROL64((A04^D4), 39); + A20 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + C0 = A00^A30^A10^A40^A20; + C1 = A21^A01^A31^A11^A41; + C2 = A42^A22^A02^A32^A12; + C3 = A13^A43^A23^A03^A33; + C4 = A34^A14^A44^A24^A04; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A01^D1), 44); + B2 = ROL64((A02^D2), 43); + B3 = ROL64((A03^D3), 21); + B4 = ROL64((A04^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+3]; + A01 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A10^D0), 3); + B3 = ROL64((A11^D1), 45); + B4 = ROL64((A12^D2), 61); + B0 = ROL64((A13^D3), 28); + B1 = ROL64((A14^D4), 20); + A10 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A20^D0), 18); + B0 = ROL64((A21^D1), 1); + B1 = ROL64((A22^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A24^D4), 8); + A20 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A30^D0), 36); + B2 = ROL64((A31^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A33^D3), 56); + B0 = ROL64((A34^D4), 27); + A30 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A40^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A42^D2), 62); + B1 = ROL64((A43^D3), 55); + B2 = ROL64((A44^D4), 39); + A40 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + } +} + +/* +** Initialize a new hash. iSize determines the size of the hash +** in bits and should be one of 224, 256, 384, or 512. Or iSize +** can be zero to use the default hash size of 256 bits. +*/ +static void SHA3Init(SHA3Context *p, int iSize){ + memset(p, 0, sizeof(*p)); + if( iSize>=128 && iSize<=512 ){ + p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; + }else{ + p->nRate = (1600 - 2*256)/8; + } +#if BYTEORDER==1234 + /* Known to be little-endian at compile-time. No-op */ +#elif BYTEORDER==4321 + p->ixMask = 7; /* Big-endian */ +#else + { + static unsigned int one = 1; + if( 1==*(unsigned char*)&one ){ + /* Little endian. No byte swapping. */ + p->ixMask = 0; + }else{ + /* Big endian. Byte swap. */ + p->ixMask = 7; + } + } +#endif +} + +/* +** Make consecutive calls to the SHA3Update function to add new content +** to the hash +*/ +static void SHA3Update( + SHA3Context *p, + const unsigned char *aData, + unsigned int nData +){ + unsigned int i = 0; +#if BYTEORDER==1234 + if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ + for(; i+7u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; + p->nLoaded += 8; + if( p->nLoaded>=p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } + } +#endif + for(; iu.x[p->nLoaded] ^= aData[i]; +#elif BYTEORDER==4321 + p->u.x[p->nLoaded^0x07] ^= aData[i]; +#else + p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; +#endif + p->nLoaded++; + if( p->nLoaded==p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } +} + +/* +** After all content has been added, invoke SHA3Final() to compute +** the final hash. The function returns a pointer to the binary +** hash value. +*/ +static unsigned char *SHA3Final(SHA3Context *p){ + unsigned int i; + if( p->nLoaded==p->nRate-1 ){ + const unsigned char c1 = 0x86; + SHA3Update(p, &c1, 1); + }else{ + const unsigned char c2 = 0x06; + const unsigned char c3 = 0x80; + SHA3Update(p, &c2, 1); + p->nLoaded = p->nRate - 1; + SHA3Update(p, &c3, 1); + } + for(i=0; inRate; i++){ + p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; + } + return &p->u.x[p->nRate]; +} + +/* +** Convert a digest into base-16. digest should be declared as +** "unsigned char digest[20]" in the calling function. The SHA3 +** digest is stored in the first 20 bytes. zBuf should +** be "char zBuf[41]". +*/ +static void DigestToBase16(unsigned char *digest, char *zBuf, int nByte){ + static const char zEncode[] = "0123456789abcdef"; + int ix; + + for(ix=0; ix>4)&0xf]; + *zBuf++ = zEncode[*digest++ & 0xf]; + } + *zBuf = '\0'; +} + + +/* +** Compute the SHA3 checksum of a file on disk. Store the resulting +** checksum in the blob pCksum. pCksum is assumed to be initialized. +** +** Return the number of errors. +*/ +static int sha3sum_file(const char *zFilename, int iSize, char *pCksum){ + FILE *in; + SHA3Context ctx; + char zBuf[10240]; + + in = fopen(zFilename,"rb"); + if( in==0 ){ + return 1; + } + SHA3Init(&ctx, iSize); + for(;;){ + int n = (int)fread(zBuf, 1, sizeof(zBuf), in); + if( n<=0 ) break; + SHA3Update(&ctx, (unsigned char*)zBuf, (unsigned)n); + } + fclose(in); + DigestToBase16(SHA3Final(&ctx), pCksum, iSize/8); + return 0; +} + +/* +** The SHA1 implementation below is adapted from: +** +** $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $ +** $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ +** +** SHA-1 in C +** By Steve Reid +** 100% Public Domain +*/ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + * + * blk0le() for little-endian and blk0be() for big-endian. + */ +#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) +/* + * GCC by itself only generates left rotates. Use right rotates if + * possible to be kinder to dinky implementations with iterative rotate + * instructions. + */ +#define SHA_ROT(op, x, k) \ + ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) +#define rol(x,k) SHA_ROT("roll", x, k) +#define ror(x,k) SHA_ROT("rorl", x, k) + +#else +/* Generic C equivalent */ +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) +#endif + + + + + +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + +static void SHA1Transform( + unsigned int state[5], + const unsigned char buffer[64] +){ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + + /* Copy context->state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + + +/* + * SHA1Init - Initialize new context + */ +static void SHA1Init(SHA1Context *context){ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* + * Run your data through this. + */ +static void SHA1Update( + SHA1Context *context, + const unsigned char *data, + unsigned int len +){ + unsigned int i, j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1] += (len>>29)+1; + j = (j >> 3) & 63; + if ((j + len) > 63) { + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1Transform(context->state, &data[i]); + j = 0; + } else { + i = 0; + } + (void)memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* + * Add padding and return the message digest. + */ +static void SHA1Final(unsigned char *digest, SHA1Context *context){ + unsigned int i; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (const unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) + SHA1Update(context, (const unsigned char *)"\0", 1); + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + + if (digest) { + for (i = 0; i < 20; i++) + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } +} + + +/* +** Compute the SHA1 checksum of a file on disk. Store the resulting +** checksum in the blob pCksum. pCksum is assumed to be initialized. +** +** Return the number of errors. +*/ +static int sha1sum_file(const char *zFilename, char *pCksum){ + FILE *in; + SHA1Context ctx; + unsigned char zResult[20]; + char zBuf[10240]; + + in = fopen(zFilename,"rb"); + if( in==0 ){ + return 1; + } + SHA1Init(&ctx); + for(;;){ + int n = (int)fread(zBuf, 1, sizeof(zBuf), in); + if( n<=0 ) break; + SHA1Update(&ctx, (unsigned char*)zBuf, (unsigned)n); + } + fclose(in); + SHA1Final(zResult, &ctx); + DigestToBase16(zResult, pCksum, 20); + return 0; +} + +/* +** Print a usage comment and quit. +*/ +static void usage(const char *argv0){ + fprintf(stderr, + "Usage: %s manifest\n" + "Options:\n" + " -v Diagnostic output\n" + , argv0); + exit(1); +} + +/* +** Find the first whitespace character in a string. Set that whitespace +** to a \000 terminator and return a pointer to the next character. +*/ +static char *nextToken(char *z){ + while( *z && !isspace(*z) ) z++; + if( *z==0 ) return z; + *z = 0; + return &z[1]; +} + + +int main(int argc, char **argv){ + const char *zManifest = 0; + int i; + int bVerbose = 0; + FILE *in; + int allValid = 1; + int rc; + SHA3Context ctx; + char zDate[50]; + char zHash[100]; + char zLine[20000]; + + for(i=1; i +#include +#include +#include +#include +#include + +#define ISDIGIT(X) isdigit((unsigned char)(X)) +#define ISPRINT(X) isprint((unsigned char)(X)) + +#if !defined(_MSC_VER) +#include +#include +#else +#include +#endif + +#include +#include + +static int fd = -1; /* The open SHM file */ + +/* Report an out-of-memory error and die. +*/ +static void out_of_memory(void){ + fprintf(stderr,"Out of memory...\n"); + exit(1); +} + +/* +** Read content from the file. +** +** Space to hold the content is obtained from malloc() and needs to be +** freed by the caller. +*/ +static unsigned char *getContent(int ofst, int nByte){ + unsigned char *aData; + aData = malloc(nByte); + if( aData==0 ) out_of_memory(); + lseek(fd, ofst, SEEK_SET); + read(fd, aData, nByte); + return aData; +} + +/* +** Flags values +*/ +#define FG_HEX 1 /* Show as hex */ +#define FG_NBO 2 /* Native byte order */ +#define FG_PGSZ 4 /* Show as page-size */ + +/* Print a line of decode output showing a 4-byte integer. +*/ +static void print_decode_line( + unsigned char *aData, /* Content being decoded */ + int ofst, int nByte, /* Start and size of decode */ + unsigned flg, /* Display flags */ + const char *zMsg /* Message to append */ +){ + int i, j; + int val = aData[ofst]; + char zBuf[100]; + sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]); + i = (int)strlen(zBuf); + for(j=1; j<4; j++){ + if( j>=nByte ){ + sprintf(&zBuf[i], " "); + }else{ + sprintf(&zBuf[i], " %02x", aData[ofst+j]); + val = val*256 + aData[ofst+j]; + } + i += (int)strlen(&zBuf[i]); + } + if( nByte==8 ){ + for(j=4; j<8; j++){ + sprintf(&zBuf[i], " %02x", aData[ofst+j]); + i += (int)strlen(&zBuf[i]); + } + } + if( flg & FG_NBO ){ + assert( nByte==4 ); + memcpy(&val, aData+ofst, 4); + } + sprintf(&zBuf[i], " "); + i += 12; + if( flg & FG_PGSZ ){ + unsigned short sz; + memcpy(&sz, aData+ofst, 2); + sprintf(&zBuf[i], " %9d", sz==1 ? 65536 : sz); + }else if( flg & FG_HEX ){ + sprintf(&zBuf[i], " 0x%08x", val); + }else if( nByte<8 ){ + sprintf(&zBuf[i], " %9d", val); + } + printf("%s %s\n", zBuf, zMsg); +} + +/* +** Print an instance of the WalIndexHdr object. ix is either 0 or 1 +** to select which header to print. +*/ +static void print_index_hdr(unsigned char *aData, int ix){ + int i; + assert( ix==0 || ix==1 ); + i = ix ? 48 : 0; + print_decode_line(aData, 0+i, 4, FG_NBO, "Wal-index version"); + print_decode_line(aData, 4+i, 4, 0, "unused padding"); + print_decode_line(aData, 8+i, 4, FG_NBO, "transaction counter"); + print_decode_line(aData,12+i, 1, 0, "1 when initialized"); + print_decode_line(aData,13+i, 1, 0, "true if WAL cksums are bigendian"); + print_decode_line(aData,14+i, 2, FG_PGSZ, "database page size"); + print_decode_line(aData,16+i, 4, FG_NBO, "mxFrame"); + print_decode_line(aData,20+i, 4, FG_NBO, "Size of database in pages"); + print_decode_line(aData,24+i, 8, 0, "Cksum of last frame in -wal"); + print_decode_line(aData,32+i, 8, 0, "Salt values from the -wal"); + print_decode_line(aData,40+i, 8, 0, "Cksum over all prior fields"); +} + +/* +** Print the WalCkptInfo object +*/ +static void print_ckpt_info(unsigned char *aData){ + const int i = 96; + int j; + print_decode_line(aData, 0+i, 4, FG_NBO, "nBackfill"); + for(j=0; j<5; j++){ + char zLabel[100]; + sprintf(zLabel, "aReadMark[%d]", j); + print_decode_line(aData, 4*j+4+i, 4, FG_NBO, zLabel); + } + print_decode_line(aData,24+i, 8, 0, "aLock"); + print_decode_line(aData,32+i, 4, FG_NBO, "nBackfillAttempted"); + print_decode_line(aData,36+i, 4, FG_NBO, "notUsed0"); +} + + +int main(int argc, char **argv){ + unsigned char *aData; + if( argc<2 ){ + fprintf(stderr,"Usage: %s FILENAME\n", argv[0]); + exit(1); + } + fd = open(argv[1], O_RDONLY); + if( fd<0 ){ + fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); + exit(1); + } + aData = getContent(0, 136); + print_index_hdr(aData, 0); + print_index_hdr(aData, 1); + print_ckpt_info(aData); + free(aData); + close(fd); + return 0; +} diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index 9db108dc26..3e08d3ffa7 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -1,7 +1,9 @@ -# Run this TCL script using "testfixture" in order get a report that shows -# how much disk space is used by a particular data to actually store data +# Run this TCL script using an SQLite-enabled TCL interpreter to get a report +# on how much disk space is used by a particular data to actually store data # versus how much space is unused. # +# The dbstat virtual table is required. +# if {[catch { @@ -147,6 +149,17 @@ if {$flags(-debug)} { db trace ::dbtrace } +# Make sure all required compile-time options are available +# +if {![db exists {SELECT 1 FROM pragma_compile_options + WHERE compile_options='ENABLE_DBSTAT_VTAB'}]} { + puts "The SQLite database engine linked with this application\ + lacks required capabilities. Recompile using the\ + -DSQLITE_ENABLE_DBSTAT_VTAB compile-time option to fix\ + this problem." + exit 1 +} + db eval {SELECT count(*) FROM sqlite_master} set pageSize [expr {wide([db one {PRAGMA page_size}])}] diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 5de218748a..96025920d3 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -29,17 +29,24 @@ SIZE=5 LEAN_OPTS="-DSQLITE_THREADSAFE=0" LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_MEMSTATUS=0" LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1" -LEAN_OPTS="$LEAN_OPTS -DSQLITE_LIKE_DOESNT_MATCH_BLOB" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_LIKE_DOESNT_MATCH_BLOBS" LEAN_OPTS="$LEAN_OPTS -DSQLITE_MAX_EXPR_DEPTH=0" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DECLTYPE" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_SHARED_CACHE" LEAN_OPTS="$LEAN_OPTS -DSQLITE_USE_ALLOCA" +BASELINE="trunk" doExplain=0 doCachegrind=1 +doVdbeProfile=0 +doWal=1 +doDiff=1 while test "$1" != ""; do case $1 in + --nodiff) + doDiff=0 + ;; --reprepare) SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" ;; @@ -61,8 +68,11 @@ while test "$1" != ""; do --temp) SPEEDTEST_OPTS="$SPEEDTEST_OPTS --temp 6" ;; + --legacy) + doWal=0 + ;; --wal) - SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal" + doWal=1 ;; --size) shift; SIZE=$1 @@ -77,6 +87,7 @@ while test "$1" != ""; do rm -f vdbe_profile.out CC_OPTS="$CC_OPTS -DVDBE_PROFILE" doCachegrind=0 + doVdbeProfile=1 ;; --lean) CC_OPTS="$CC_OPTS $LEAN_OPTS" @@ -116,17 +127,32 @@ while test "$1" != ""; do --orm) SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset orm" ;; - *) + --cte) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset cte" + ;; + --fp) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset fp" + ;; + -*) CC_OPTS="$CC_OPTS $1" ;; + *) + BASELINE=$1 + ;; esac shift done +if test $doWal -eq 1; then + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal" +fi SPEEDTEST_OPTS="$SPEEDTEST_OPTS --size $SIZE" echo "NAME = $NAME" | tee summary-$NAME.txt echo "SPEEDTEST_OPTS = $SPEEDTEST_OPTS" | tee -a summary-$NAME.txt echo "CC_OPTS = $CC_OPTS" | tee -a summary-$NAME.txt rm -f cachegrind.out.* speedtest1 speedtest1.db sqlite3.o +if test $doVdbeProfile -eq 1; then + rm -f vdbe_profile.out +fi $CC -g -Os -Wall -I. $CC_OPTS -c sqlite3.c size sqlite3.o | tee -a summary-$NAME.txt if test $doExplain -eq 1; then @@ -147,10 +173,16 @@ size sqlite3.o | tee -a summary-$NAME.txt wc sqlite3.c if test $doCachegrind -eq 1; then cg_anno.tcl cachegrind.out.* >cout-$NAME.txt + echo '*****************************************************' >>cout-$NAME.txt + sed 's/^[0-9=-]\{9\}/==00000==/' summary-$NAME.txt >>cout-$NAME.txt fi if test $doExplain -eq 1; then ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt fi -if test "$NAME" != "trunk"; then - fossil test-diff --tk -c 20 cout-trunk.txt cout-$NAME.txt +if test $doVdbeProfile -eq 1; then + tclsh ../sqlite/tool/vdbe_profile.tcl >vdbeprofile-$NAME.txt + open vdbeprofile-$NAME.txt +fi +if test "$NAME" != "$BASELINE" -a $doVdbeProfile -ne 1 -a $doDiff -ne 0; then + fossil test-diff --tk -c 20 cout-$BASELINE.txt cout-$NAME.txt fi diff --git a/tool/split-sqlite3c.tcl b/tool/split-sqlite3c.tcl index 287b752828..230e3f2549 100644 --- a/tool/split-sqlite3c.tcl +++ b/tool/split-sqlite3c.tcl @@ -15,6 +15,7 @@ set END {^/\*+ End of %s \*+/} set in [open sqlite3.c] set out1 [open sqlite3-all.c w] +fconfigure $out1 -translation lf # Copy the header from sqlite3.c into sqlite3-all.c # @@ -48,6 +49,7 @@ proc write_one_file {content} { global filecnt incr filecnt set out [open sqlite3-$filecnt.c w] + fconfigure $out -translation lf puts -nonewline $out $content close $out puts $::out1 "#include \"sqlite3-$filecnt.c\"" diff --git a/tool/sqldiff.c b/tool/sqldiff.c index b31489bfd7..509470a156 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -134,28 +134,8 @@ static void strPrintf(Str *p, const char *zFormat, ...){ ** needed. */ static char *safeId(const char *zId){ - /* All SQLite keywords, in alphabetical order */ - static const char *azKeywords[] = { - "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", - "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", - "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", - "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", - "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", - "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", - "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", - "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", - "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", - "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", - "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", - "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", - "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", - "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", - "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", - "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", - "WITH", "WITHOUT", - }; - int lwr, upr, mid, c, i, x; + int i, x; + char c; if( zId[0]==0 ) return sqlite3_mprintf("\"\""); for(i=x=0; (c = zId[i])!=0; i++){ if( !isalpha(c) && c!='_' ){ @@ -166,20 +146,10 @@ static char *safeId(const char *zId){ } } } - if( x ) return sqlite3_mprintf("%s", zId); - lwr = 0; - upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; - while( lwr<=upr ){ - mid = (lwr+upr)/2; - c = sqlite3_stricmp(azKeywords[mid], zId); - if( c==0 ) return sqlite3_mprintf("\"%w\"", zId); - if( c<0 ){ - lwr = mid+1; - }else{ - upr = mid-1; - } + if( x || !sqlite3_keyword_check(zId,i) ){ + return sqlite3_mprintf("%s", zId); } - return sqlite3_mprintf("%s", zId); + return sqlite3_mprintf("\"%w\"", zId); } /* diff --git a/tool/sqlite3_analyzer.c.in b/tool/sqlite3_analyzer.c.in new file mode 100644 index 0000000000..e830521e08 --- /dev/null +++ b/tool/sqlite3_analyzer.c.in @@ -0,0 +1,29 @@ +/* +** Read an SQLite database file and analyze its space utilization. Generate +** text on standard output. +*/ +#define TCLSH_INIT_PROC sqlite3_analyzer_init_proc +#define SQLITE_ENABLE_DBSTAT_VTAB 1 +#undef SQLITE_THREADSAFE +#define SQLITE_THREADSAFE 0 +#undef SQLITE_ENABLE_COLUMN_METADATA +#define SQLITE_OMIT_DECLTYPE 1 +#define SQLITE_OMIT_DEPRECATED 1 +#define SQLITE_OMIT_PROGRESS_CALLBACK 1 +#define SQLITE_OMIT_SHARED_CACHE 1 +#define SQLITE_DEFAULT_MEMSTATUS 0 +#define SQLITE_MAX_EXPR_DEPTH 0 +#define SQLITE_OMIT_LOAD_EXTENSION 1 +#ifndef USE_EXTERNAL_SQLITE +INCLUDE sqlite3.c +#endif +INCLUDE $ROOT/src/tclsqlite.c + +const char *sqlite3_analyzer_init_proc(Tcl_Interp *interp){ + (void)interp; + return +BEGIN_STRING +INCLUDE $ROOT/tool/spaceanal.tcl +END_STRING +; +} diff --git a/tool/sqltclsh.c.in b/tool/sqltclsh.c.in new file mode 100644 index 0000000000..da354ee935 --- /dev/null +++ b/tool/sqltclsh.c.in @@ -0,0 +1,51 @@ +/* +** This is the source code to a "tclsh" that has SQLite built-in. +** +** The startup script is located as follows: +** +** (1) Open the executable as an appended SQLite database and try to +** read the startup script out of that database. +** +** (2) If the first argument is a readable file, try to open that file +** as an SQLite database and read the startup script out of that +** database. +** +** (3) If the first argument is a readable file with a ".tcl" extension, +** then try to run that script directly. +** +** If none of the above steps work, then the program runs as an interactive +** tclsh. +*/ +#define TCLSH_INIT_PROC sqlite3_tclapp_init_proc +#define SQLITE_ENABLE_DBSTAT_VTAB 1 +#undef SQLITE_THREADSAFE +#define SQLITE_THREADSAFE 0 +#undef SQLITE_ENABLE_COLUMN_METADATA +#define SQLITE_OMIT_DECLTYPE 1 +#define SQLITE_OMIT_DEPRECATED 1 +#define SQLITE_OMIT_PROGRESS_CALLBACK 1 +#define SQLITE_OMIT_SHARED_CACHE 1 +#define SQLITE_DEFAULT_MEMSTATUS 0 +#define SQLITE_MAX_EXPR_DEPTH 0 +INCLUDE sqlite3.c +INCLUDE $ROOT/ext/misc/appendvfs.c +#ifdef SQLITE_HAVE_ZLIB +INCLUDE $ROOT/ext/misc/zipfile.c +INCLUDE $ROOT/ext/misc/sqlar.c +#endif +INCLUDE $ROOT/src/tclsqlite.c + +const char *sqlite3_tclapp_init_proc(Tcl_Interp *interp){ + (void)interp; + sqlite3_appendvfs_init(0,0,0); +#ifdef SQLITE_HAVE_ZLIB + sqlite3_auto_extension((void(*)(void))sqlite3_sqlar_init); + sqlite3_auto_extension((void(*)(void))sqlite3_zipfile_init); +#endif + + return +BEGIN_STRING +INCLUDE $ROOT/tool/sqltclsh.tcl +END_STRING +; +} diff --git a/tool/sqltclsh.tcl b/tool/sqltclsh.tcl new file mode 100644 index 0000000000..6a4b1fe1f0 --- /dev/null +++ b/tool/sqltclsh.tcl @@ -0,0 +1,71 @@ +# Try to open the executable as a database and read the "scripts.data" +# field where "scripts.name" is 'main.tcl' +# +catch { + if {![file exists $argv0] && [file exists $argv0.exe]} { + append argv0 .exe + } + sqlite3 db $argv0 -vfs apndvfs -create 0 + set mainscript [db one { + SELECT sqlar_uncompress(data,sz) FROM sqlar WHERE name='main.tcl' + }] +} +if {[info exists mainscript]} { + eval $mainscript + return +} else { + catch {db close} +} + +# Try to open file named in the first argument as a database and +# read the "scripts.data" field where "scripts.name" is 'main.tcl' +# +if {[llength $argv]>0 && [file readable [lindex $argv 0]]} { + catch { + sqlite3 db [lindex $argv 0] -vfs apndvfs -create 0 + set mainscript [db one {SELECT data FROM scripts WHERE name='main.tcl'}] + set argv0 [lindex $argv 0] + set argv [lrange $argv 1 end] + } + if {[info exists mainscript]} { + eval $mainscript + return + } else { + catch {db close} + } + if {[string match *.tcl [lindex $argv 0]]} { + set fd [open [lindex $argv 0] rb] + set mainscript [read $fd] + close $fd + unset fd + set argv0 [lindex $argv 0] + set argv [lrange $argv 1 end] + } + if {[info exists mainscript]} { + eval $mainscript + return + } +} + +# If all else fails, do an interactive loop +# +set line {} +while {![eof stdin]} { + if {$line!=""} { + puts -nonewline "> " + } else { + puts -nonewline "% " + } + flush stdout + append line [gets stdin] + if {[info complete $line]} { + if {[catch {uplevel #0 $line} result]} { + puts stderr "Error: $result" + } elseif {$result!=""} { + puts $result + } + set line {} + } else { + append line \\n" + } +} diff --git a/tool/tostr.tcl b/tool/tostr.tcl deleted file mode 100644 index cb06ee947f..0000000000 --- a/tool/tostr.tcl +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/tcl -# -# Convert input text into a C string -# -set in [open [lindex $argv 0] rb] -while {![eof $in]} { - set line [gets $in] - if {[eof $in]} break; - set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line] - puts "\"$x\\n\"" -} -close $in diff --git a/tool/warnings-clang.sh b/tool/warnings-clang.sh index 7a0aa4bce7..6dcc086d2f 100644 --- a/tool/warnings-clang.sh +++ b/tool/warnings-clang.sh @@ -3,12 +3,12 @@ # Run this script in a directory with a working makefile to check for # compiler warnings in SQLite. # -rm -f sqlite3.c -make sqlite3.c +rm -f sqlite3.c shell.c +make sqlite3.c shell.c echo '************* FTS4 and RTREE ****************' scan-build gcc -c -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ -DSQLITE_DEBUG -DSQLITE_ENABLE_STAT3 sqlite3.c 2>&1 | grep -v 'ANALYZE:' echo '********** ENABLE_STAT3. THREADSAFE=0 *******' scan-build gcc -c -I. -DSQLITE_ENABLE_STAT3 -DSQLITE_THREADSAFE=0 \ -DSQLITE_DEBUG \ - sqlite3.c ../sqlite/src/shell.c -ldl 2>&1 | grep -v 'ANALYZE:' + sqlite3.c shell.c -ldl 2>&1 | grep -v 'ANALYZE:'